简体   繁体   中英

C: Reading pairs of ints from user until newline (scanf, sscanf, fgets and friends)

I'm trying to read unknown pairs from stdin, until a new line is entered.

Input example:

Enter something:

5

Enter pairs:

1 3 4 2 5 2 5 4

What's the best method of doing that? I've tried several of methods, including fgets & sscanf - but couldn't get the expected outcome.

Here's what I've tried, but I keep missing the \\n:

Method #1:

while (1)
{
    scanf("%d %d", &a, &b);

    // do something with a,b

    if (getchar() == '\n')
        break;
}

Method #2:

while (scanf("%d %d", &a, &b) == 2)
{
    // do something with a,b

    if (getchar() == '\n')
        break;
}

I keep getting into an infinite loop - what am I doing wrong?

I believe the easiest way to handle spaces at the end of the line -- which is what probably causes your problem -- is to read the line in advance and parse it with sscanf . It could look roughly like this:

#include <stdio.h>

int main() {
  char line[1024];
  char const *p;
  int x, y;
  int n;

  fgets(line, 1024, stdin);

  for(p = line; sscanf(p, " %d %d%n", &x, &y, &n) == 2; p += n) {
    printf("%d %d %d\n", x, y, n); // to show you what happens
  }

  return 0;
}

Here the %n makes sscanf tell you the number of characters that has been processed up to that point, and we use that number to advance our read pointer in every iteration.

This handles an uneven number of numbers in a line by ignoring the last one, which may or may not be what you want to happend.

you get an infinite loop because the next character after the last digit read is not a newline but a space

so if you enter this input

1 3 4 2 5 2 5 4 

which is

1<space>3<space>4<space>2<space>5<space>2<space>5<space>4<Enter>

you can make it work (please note the last character in the input just after the last digit 4)

let's analyze the example above

1<space>3<space>
|       |  |-----> will be stored in getchar()
|       |--------> will be stored in b 
|----------------> will be stored in a 

so for the last two digits if you hit a space instead of enter button this is what happens

5<space>4<space>
|       |  |-----> will be stored in getchar() which is not newline 
|       |          so it will generate another loop 
|       |--------> will be stored in b 
|----------------> will be stored in a 

so the program will wait for digit to be entered as another loop is created and stuck there because there is no digits left !!

to get rid of that problem you can store the whole line in a string using fgets() function and after that you get the pair of digit from it using the sscanf() function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM