fgets() 没有扫描我想要的字符串数

fgets() not scanning the number of strings I want

我有一个句子数组,我想先用fgets()扫描它们,然后一个一个打印出来。这是程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>





int main(int argc,char *argv[]) {

    char sentence[100][100]; /* 100 sentences with at most 100 characters*/
    int n,i,j;

    scanf("%d",&n); /* number of sentences*/

    for (i=0;i<n;i++) {
        fgets(sentence[i],100,stdin);
    }
    printf("****************************");
    for (i=0;i<n;i++) {
        for(j=0;j<strlen(sentence[i]);j++) {
            putchar(sentence[i][j]);
        }

    }


    return 0;
}

问题是这只扫描了n-1个句子。这是为什么?

另一个奇怪的事情是,在打印星号之后,它在我没有告诉它这样做的情况下开始在一个新行打印。

您是否阅读了 fgets 的手册页?

fgets() 从流中读入最多小于 size 个字符,并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止阅读。如果读取到换行符,则将其存储到缓冲区中。终止空字节 ('\0') 存储在缓冲区中的最后一个字符之后。

因此,正如 chux 所指出的那样,您的代码应该是:

fgets(sentence[i],sizeof sentence[i],stdin);

假设输入是

3
abc
def
ghi

扫描n后光标停留在第一行第3号后

你可以在%d后面加一个space,比如scanf("%d ", &n);,把光标移动到下一行。 (这假设第一句不以 spaces 开头)。

取决于你的环境是否是(Windows / Unix),以及你是否希望每个字符串都保留行尾字符,你需要将缓冲区大小增加到:

  • 101 - 对于 Unix 行尾,对于 100 个字符长的句子,您可以丢弃行尾字符
  • 102 - 对于 Windows 行结束,您可以丢弃 100 个字符长的句子的行尾字符
  • 102 - 用于 Unix 行结束并且您想为所有句子保留行结束字符
  • 103 - 对于 Windows 行结束并且您想为所有句子保留行尾字符

例如,如果您错误地将 101 用于 Windows,则对于以下输入

0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789

输出将是:

0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789


0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789


0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789

(有些空行)

两种情况都将由一个概念解决,fgets()newline视为输入的一部分。

问题 1:

您在输入缓冲区中留下了一个 newline(由于在第一次输入后按下 ENTER 键),它被紧接的下一个 fgets().

拾取

解决问题 1:

使用

  scanf("%d%*c",&n);   //simple solution

 scanf("%d",&n);
 while (getchar() != '\n');  //eat up anything upto newline

清除结尾的换行符。

问题 2:

fgets() 根据输入扫描并存储 newline。如果您不希望换行符作为输入的一部分,您必须手动检查并删除它。

手册页中的相关引用:

[...] If a newline is read, it is stored into the buffer. [...]

解决问题 2:

  sentence[strcspn(sentence, "\r\n")] = 0;

感谢@chux, more about this here