C:从用户读取成对的整数直到换行(scanf、sscanf、fgets 和朋友)
C: Reading pairs of ints from user until newline (scanf, sscanf, fgets and friends)
我正在尝试从标准输入读取未知对,直到输入新行。
输入示例:
Enter something:
5
Enter pairs:
1 3 4 2 5 2 5 4
最好的方法是什么?我已经尝试了几种方法,包括 fgets 和 sscanf - 但无法获得预期的结果。
这是我试过的方法,但我总是错过\n:
方法一:
while (1)
{
scanf("%d %d", &a, &b);
// do something with a,b
if (getchar() == '\n')
break;
}
方法二:
while (scanf("%d %d", &a, &b) == 2)
{
// do something with a,b
if (getchar() == '\n')
break;
}
我一直陷入无限循环 - 我做错了什么?
你得到一个无限循环,因为读取的最后一个数字后的下一个字符不是换行符而是 space
所以如果你输入这个输入
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
所以对于最后两位数字,如果您点击 space 而不是输入按钮,就会发生这种情况
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()
函数从中获取一对数字
我认为处理行尾空格的最简单方法(这可能是导致您出现问题的原因)是提前阅读该行并使用 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
告诉您到目前为止已处理的字符数,我们使用该数字在每次迭代中推进我们的读取指针。
这会通过忽略最后一个数字来处理一行中数量不均匀的数字,这可能是也可能不是您想要发生的情况。
我正在尝试从标准输入读取未知对,直到输入新行。
输入示例:
Enter something:
5
Enter pairs:
1 3 4 2 5 2 5 4
最好的方法是什么?我已经尝试了几种方法,包括 fgets 和 sscanf - 但无法获得预期的结果。
这是我试过的方法,但我总是错过\n:
方法一:
while (1)
{
scanf("%d %d", &a, &b);
// do something with a,b
if (getchar() == '\n')
break;
}
方法二:
while (scanf("%d %d", &a, &b) == 2)
{
// do something with a,b
if (getchar() == '\n')
break;
}
我一直陷入无限循环 - 我做错了什么?
你得到一个无限循环,因为读取的最后一个数字后的下一个字符不是换行符而是 space
所以如果你输入这个输入
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
所以对于最后两位数字,如果您点击 space 而不是输入按钮,就会发生这种情况
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()
函数从中获取一对数字
我认为处理行尾空格的最简单方法(这可能是导致您出现问题的原因)是提前阅读该行并使用 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
告诉您到目前为止已处理的字符数,我们使用该数字在每次迭代中推进我们的读取指针。
这会通过忽略最后一个数字来处理一行中数量不均匀的数字,这可能是也可能不是您想要发生的情况。