How do I read white space using scanf in c?

醉酒当歌 提交于 2019-11-28 10:06:44

getc and ungetc are your friends

#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

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

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

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

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

If you really want scanf type functionality, you can use fgets and sscanf, and use the %n specifier 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.

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

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.

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.

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 %d chews up leading white space (as defined by the standard) - all of them.

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

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

#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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!