获取N个字符串时使用fgets() / gets()函数出现问题。在初始位置未能获取输入。

4
我需要获取用户输入的 n 个字符串。为此,我首先定义了一个二维数组 char str[ ][ ]。
我使用 for 循环从用户处获得输入,并尝试了 gets() 和 fgets() 两种方法。在代码示例中,尽管我使用了 gets(),但它总是只取 n-1 个字符串,即比用户要求的少一个。
在进一步检查后,我发现程序没有为第 0 个字符串即初始字符串获取输入。
我的代码:
#include <stdio.h>
int main(void){
int i, n;

printf("how many string you want to enter: ");
scanf("%d", &n);

char str[n][60];

printf("start entering strings:\n ");

for(i=0;i<n;i++){     
    gets(str[i]);     //have used here fgets() also
}

puts(str[0]);         //no output for Oth string
return 0;
}

输出:

how many string you want to enter:

用户输入 - 3

how many string you want to enter: 3
start entering strings:

最终输出:

how many string you want to enter: 3
start entering strings:
 abc
bcd

在输入了两个字符串后,程序就终止了,并且没有输出puts(str[0]);

尽管使用scanf()按照scanf("%s", str[i]);的方式输入可以正常工作。
我想知道为什么使用gets()fgets()不起作用。


1
首先,永远不要使用 gets。它是一个危险的函数,因此甚至已被从 C 标准中移除。 - Some programmer dude
已尝试使用fgets,但问题是它无法为str [0]输入数据。 - Vartika
2个回答

4

您需要使用scanf剩余的缓冲区:

scanf("%d", &n);
char str[n][60];
int c;
while ((c = fgetc(stdin)) != '\n' && c != EOF);
printf("start entering strings:\n ");

使用fgetsstrtol代替scanf,您就可以避免丑陋的刷新循环:

char buf[32];
int i, n = 0;

printf("how many string you want to enter: ");
if (fgets(buf, sizeof buf, stdin)) {
    n = (int)strtol(buf, NULL, 10);
}

char str[n][60];
printf("start entering strings:\n ");

我不明白。 - Vartika
你在另一个答案中得到了@Someprogrammerdude 的优美解释。 - David Ranieri
2
@asynts,这就是为什么我建议使用fgetsstrtol,你也可以使用第二个参数检查输入是否有效,但这留给OP自己练习 :) - David Ranieri

2
问题不在于fgets(或者说,对于此问题,也不在于gets)。问题在于你之前调用了scanf函数。
当你使用Enter键结束输入数字时,该Enter键将作为换行符添加到输入缓冲区中。因此,在scanf读取数字后,下一个字符保留在输入缓冲区中的是那个换行符。这就是fgets将要阅读的第一个字符,即一个空行。所以,它确实会读取所有行,但第一行将被视为空行。
这就是为什么你似乎没有得到任何输出的原因,因为没有可打印的字符可以打印。你得到的只是一个空行。

1
我认为,最大的问题是- 我在学习C语言时使用了错误的教材。 :( - Vartika
社区能帮助我选择正确的源代码吗? - Vartika
2
@Vartika 选择[c]标签,然后点击“了解更多”,那里有很多提示,包括资源和书籍:https://stackoverflow.com/tags/c/info。 - David Ranieri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接