关于 fgets() 函数字符限制的 C 编程?

C programming on fgets() function characters limitation?

示例代码:

    int i;
    char word [10][15];
    for (i = 0; i < 10; i++){

      fgets(word[i], 16, stdin);

    }

所以我(最多)接收 10 个字符串用户输入,每个字符串的长度不能超过 15 个字符(因此 16,因为 \n 存储在fgets() 方法,对吧?)。

我的问题是当我想打印出单词数组中的单词时。发生这种情况:

输入:

abcdefghijklmnopqrstuvwxyz

输出:

abcdefghijklmnopqrstuvwxyz

pqrstuvwxyz

我不知道为什么会这样。似乎 fgets() 在输入 15 个字符后不会停止。

编辑:

    int j;
    for (j = 0; j < 10; j++){
      printf("%s", word[j]);
    }

请记住,在 C 编程语言中,每个字符串都以尾随 [=13=] 字节结尾。 fgets 函数读取的字符最多比您允许它写入缓冲区的字符少一个,因此它可以用 [=13=] 字节终止缓冲区中的字符串。现在,在您的代码中,您允许 fgetsword 中的每个 char[15] 多写入一个字节到 word。最初,word 数组如下所示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

其中 ? 代表一个未定义的值。在你的代码第一次调用 fgets 之后,words 看起来像这样:

a b c d e f g h i j k l m n o [=11=]? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

观察到fgetswords[0]中的space多写了一个字节,所以写入了属于word[1]的space。然而,如果你要用 printf 打印出 word[0] 的内容,字符串 abcdefghijklmno 将被打印为 printf 直到遇到 [=13=] 字节.现在看看在第二次调用 fgets:

之后 word 的样子
a b c d e f g h i j k l m n o p q r s t u v w x y z \n[=12=]? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

在此调用中,fgets 不会写入超出 word[1] 的末尾,因为它之前遇到了一个换行符 (\n) 字节。观察 word[0] 中字符串的尾随 [=13=] 字节已被覆盖,因为该字符串进入了 word[1].

占用的内存区域

现在如果你打印会发生什么?第一次调用 printfa 开始打印,直到遇到 [=13=] 字符。这导致字符串 abcdefghijklmnopqrstuvwxyz\n 被打印出来,因为 o 后面没有 [=13=] 字节。 printf 的第二次调用从 word[1] 开始的地方开始,在 p 直到它看到 [=13=],导致打印 pqrstuvwxyz\n

现在你如何解决这个问题?要么让数组中的每个字符串更长,要么让 fgets 只读取 15 而不是 16 个字符。