C语言 如何在c中使用scanf读取空格?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3765023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:29:14  来源:igfitidea点击:

How do I read white space using scanf in c?

cwhitespacescanffgets

提问by MykC

Problem: I need to be able identify when two whitespaces occur consecutively.

问题:我需要能够识别连续出现两个空格的时间。

I have read the following questions:

我已阅读以下问题:

how to read a string from a \n delimited file

如何从 \n 分隔的文件中读取字符串

how to read scanf with spaces

如何读取带有空格的 scanf

And I am aware of scanf problems: http://c-faq.com/stdio/scanfprobs.html

而且我知道 scanf 问题:http: //c-faq.com/stdio/scanfprobs.html

Input will be in the following format:

输入将采用以下格式:

1 5 3 2  4 6 2  1 9  0

Two white spaces indicates that the next set of data needs to be handle and compared to itself. The length of the line is unknown and the number or integers in each group is unknown. Two whitespaces is the most that will separate the next data set.

两个空格表示需要处理下一组数据并与自身进行比较。行的长度未知,每组中的数字或整数未知。两个空格最多可以分隔下一个数据集。

While I can use fgets and various built in functions to solve this problem, I am at the point where solving the problem with scanf at this point will likely be easier. However, if that's not the case, using fgets, strtok and atoi will do most of the job but I still need to identify two whitespaces in a row.

虽然我可以使用 fgets 和各种内置函数来解决这个问题,但我现在使用 scanf 解决问题可能会更容易。但是,如果不是这种情况,使用 fgets、strtok 和 atoi 将完成大部分工作,但我仍然需要连续识别两个空格。

The below will take integers until a non-integer is inputed.

下面将采用整数,直到输入非整数。

while ( scanf ( "%d", &x ) == 1 )

What I need it do is read whitespaces as well and if there is two consecutive whitespaces I'll the program to do something different with the next set of data.

我需要它做的是读取空格,如果有两个连续的空格,我会让程序对下一组数据做一些不同的事情。

And once I do get a white space I don't know how to say:

一旦我得到一个空白,我不知道怎么说:

if ((input == "whitespace") && (previousInput == "whitespace"))
  ya da ya da
else (input == "whitespace")
  ya da ya da
else 
  ya da ya da

I appreciate your time and thank you for your help.

我感谢您的时间并感谢您的帮助。

Lesson learned:While a solution for scanf is posted below by Jonathan Leffler, the solution was a bit more straightforward with getc (by way of requiring less intimate knowledge of the inner scanf, regular expressions and char). In retrospect better knowledge of regular expressions, scanf and char would of made the problem easier and of course knowing what functions are available and which one would have been the best one to use from the start.

经验教训:虽然 Jonathan Leffler 在下面发布了 scanf 的解决方案,但 getc 的解决方案更简单一些(通过对内部 scanf、正则表达式和字符的了解较少)。回想一下对正则表达式的更好了解, scanf 和 char 会使问题变得更容易,并且当然知道哪些函数可用以及哪个函数从一开始就最好使用。

采纳答案by pmg

getcand ungetcare your friends

getcungetc是你的朋友

#include <stdio.h>

int main(void) {
  int ch, spaces, x;
  while (1) {
    spaces = 0;
    while (((ch = getc(stdin)) != EOF) && (ch == ' ')) spaces++;
    if (ch == EOF) break;
    ungetc(ch, stdin);
    if (scanf("%d", &x) != 1) break;
    printf("%d was preceded by %d spaces\n", x, spaces);
  }
  return 0;
}

Demo at http://ideone.com/xipm1

演示在http://ideone.com/xipm1

EditRahhhhhhhhh ... I uploaded that as C++. Here's the exact same thing, but now C99 strict( http://ideone.com/mGeVk)

编辑Rahhhhhhhh... 我将其上传为 C++。这是完全相同的事情,但现在C99 stricthttp://ideone.com/mGeVk

回答by Svisstack

while ( scanf ( "%c", &x ) == 1 )

Using %cyou can read whitespace characters, you must only read all data and store in array. Then allocate char* cptrand get set cptrto begin of array, then you analyze your array and if you want read decimal numbers, you can use simply sscanfon cptrwhile you want read decimal, but you must have pointer in good position on array (on number what you wany read)

使用%c您可以读取空白字符,您必须只读取所有数据并存储在数组中。然后分配char* cptr并设置cptr为数组的开头,然后分析你的数组,如果你想读取十进制数,你可以sscanf在想要读取十进制数时简单地使用cptr,但你必须在数组上有一个正确位置的指针(在你想要的数字上)读)

if (((*(cptr + 1)) == ' ') && ((*cptr)== ' '))
  ya da ya da
else ((*cptr)== ' '))
  ya da ya da
  sscanf(++cptr, "%d", &x);
else 
  ya da ya da

回答by Jonathan Leffler

What is your definition of 'white space'?

你对“空白”的定义是什么?

Frankly, I don't think I'd want to try using scanf()to identify double white spaces; nearly every other method would be far easier.

坦率地说,我不认为我想尝试使用scanf()来识别双空格;几乎所有其他方法都会容易得多。

However, if you insist on doing the not desperately sensible, then you might want to use code derived from the following:

但是,如果您坚持做不完全明智的事情,那么您可能希望使用从以下内容派生的代码:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int d;
    char sp[3] = "";
    int n;

    while ((n = scanf("%d%2[ \t]", &d, sp)) > 0)
    {
        printf("n = %d; d = %d; sp = <<%s>>", n, d, sp);
        if (n == 2 && strlen(sp) == 2)
            printf(" end of group");
        putchar('\n');
    }
    return 0;
}

The square brackets enclose a character class and the 2 before it insists on at most 2 characters from the class. You might have to worry about it reading the newline and trying to get more data to satisfy the character class - which could be resolved by removing the newline from the character class. But then it hinges on your definition of white space, and whether groups are automatically ended by a newline or not. It wouldn't hurt to reset sp[0] = '\0';at the end of the loop.

方括号将一个字符类和 2 括起来,然后它坚持该类中最多 2 个字符。您可能不得不担心它读取换行符并尝试获取更多数据以满足字符类 - 这可以通过从字符类中删除换行符来解决。但是这取决于您对空白的定义,以及组是否自动以换行符结束。sp[0] = '\0';在循环结束时重置不会有什么坏处。

You might, perhaps, be better off reversing the fields, to detect two spaces before a number. But that would fail in the ordinary case, so then you'd fall back on a simple "%d"format to read the number (and if that fails, you know you got neither spaces nor a number - error). Note that %dchews up leading white space (as defined by the standard) - all of them.

您可能最好颠倒字段以检测数字前的两个空格。但是在普通情况下这会失败,所以你会回到一个简单的"%d"格式来读取数字(如果失败,你知道你既没有空格也没有数字 - 错误)。请注意,%d咀嚼前导空白(如标准所定义) - 所有这些。

The more I look at this, the less I like 'scanf()only. Remind me not to take a class at your university, please.

我越看这个,我就越不喜欢'scanf()只。请提醒我不要在你的大学上课。

回答by R.. GitHub STOP HELPING ICE

If you really want scanftype functionality, you can use fgetsand sscanf, and use the %nspecifier to get scanf to give your program the offsets for the beginning and end of each whitespace span at the same time it does the rest of its work.

如果你真的想要scanf类型功能,你可以使用fgetsand sscanf,并使用说明%n符来获取 scanf 为你的程序提供每个空白跨度的开头和结尾的偏移量,同时它完成其余的工作。

Otherwise, ditch the whole scanffamily. It's quite possibly the most useless part of the standard library, in my opinion.

否则,抛弃整个scanf家庭。在我看来,这很可能是标准库中最无用的部分。

回答by Indinfer

Here is a solution that uses only the scanf() function. I used sscanf() in this sample for about the same functionality.

这是一个仅使用 scanf() 函数的解决方案。我在本示例中使用了 sscanf() 来实现大致相同的功能。

#include <stdio.h>


int p_1_cnt = 0, p_2_cnt = 0;

void process_1(int x)
{
    p_1_cnt++;
}


void process_2(int x)
{
    p_2_cnt++;
}


char * input_line = "1 5 3 2  4 6 2  1 9  0";

int main(void)
{
    char * ip = input_line;

    int x = 0, ws_0 = 0, ws_1 = 0, preceding_spaces = 1, fields = -2;

    while (sscanf (ip, "%d%n %n", &x, &ws_0, &ws_1) > 0)
    {
        ip += ws_0;

        if ((preceding_spaces) == 1)
            process_1(x);
        else
            process_2(x);

        preceding_spaces = ws_1 - ws_0;
    }

    printf("\np_1_cnt = %d, p_2_cnt = %d", p_1_cnt, p_2_cnt);
    _fgetchar();

    return 0;
}