【问题标题】:C programming on fgets() function characters limitation?关于 fgets() 函数字符限制的 C 编程?
【发布时间】:2015-05-28 10:37:30
【问题描述】:

示例代码:

    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]);
    }

【问题讨论】:

  • 我可以看看你的整个代码,包括你用来打印word数组的代码吗?仅使用部分代码很难。
  • 好的,我会编辑对不起
  • 另外,您的语法不正确(char[10][15] word; 不是正确的 C 语法)。此代码不会编译。请发布实际代码。
  • 我会立即尝试,但我在某处读到,为了接收 n 个字符,必须设置 n + 1?我可能读错了我也编辑了那部分。对此感到抱歉
  • 我将 fgets 更改为 fgets(words[i], 15, stdin),但现在它只需要 14 个字符。那么如何存储15个字符呢?编辑:哦,我明白了,谢谢

标签: c char fgets


【解决方案1】:

请记住,在 C 编程语言中,每个字符串都以结尾的 \0 字节结尾。 fgets 函数读取的字符最多比您允许它写入缓冲区的字符少一个,因此它可以用 \0 字节终止缓冲区中的字符串。现在,在您的代码中,您允许fgets 比word 中的每个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 \0? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

观察到fgets 比words[0] 中的空间多写了一个字节,所以它写入了属于word[1] 的空间。然而,如果你用printf 打印出word[0] 的内容,则字符串abcdefghijklmno 将打印为printf,直到遇到\0 字节。现在看看word 在第二次调用fgets 后的样子:

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\0? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

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

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

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

【讨论】:

    猜你喜欢
    • 2015-06-22
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 2019-06-01
    • 2013-11-20
    • 2019-02-08
    相关资源
    最近更新 更多