C:从用户读取一对int到newline(scanf,sscanf,fgets和friends)

时间:2015-01-18 12:46:31

标签: c input fgets scanf

我正在尝试从stdin读取未知对,直到输入新行。

输入示例:

  

输入内容:

     

5

     

输入对:

     

1 3 4 2 5 2 5 4

这样做的最佳方法是什么?我尝试了几种方法,包括fgets& sscanf - 但无法获得预期的结果。

这是我尝试过的,但我一直想念\ n:

方法#1:

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

    // do something with a,b

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

方法#2:

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

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

我一直陷入无限循环 - 我做错了什么?

2 个答案:

答案 0 :(得分:2)

我认为在行尾处理空格的最简单方法 - 这可能是导致问题的原因 - 是提前读取行并用sscanf解析它。它看起来大致如下:

#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;
}

此处%n使sscanf告诉您到目前为止已处理的字符数,并且我们使用该数字在每次迭代中推进我们的读指针。

通过忽略最后一个数字来处理行中数字的不均匀数量,这可能是您想要发生的,也可能不是。

答案 1 :(得分:1)

你得到一个无限循环,因为最后一个数字读取后的下一个字符不是换行符而是空格

所以如果你输入这个输入

1 3 4 2 5 2 5 4 

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

你可以使它工作(请注意最后一个数字4之后的输入中的最后一个字符)

让我们分析上面的例子

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

所以对于最后两位数字,如果你按空格而不是输入按钮,这就是发生的事情

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 

所以程序会等待输入数字,因为没有数字会产生另一个循环并卡在那里!!

要摆脱这个问题,你可以使用fgets()函数将整行存储在一个字符串中,然后使用sscanf()函数从中获取一对数字