【问题标题】:Error in printing array of strings in C在 C 中打印字符串数组时出错
【发布时间】:2014-09-18 04:57:07
【问题描述】:

我有一个简单的程序来输入 5 个字符串的数组并输出它们。但是输出有些奇怪。以下是我的代码。

#include <stdio.h>

int main()
{
    char a[10][5];
    int i;
    for(i=0; i<5; ++i)
    {
        printf("\nEnter the name of %d st student:", i+1);
        fflush(stdout);
        gets(a[i]);
    }
    for(i=0; i<5; ++i)
    {
        printf("\n%s", a[i]);
        fflush(stdout);
    }
    return 0;
}

我将输入作为 tom、john、peter、david 和 alan 给出,我得到以下输出。

tom
john
peterdavidalan
davidalan
alan

可能是什么问题?

【问题讨论】:

  • char a[10][5] 有 10 个字符串的空间,每个字符串最多 4 个字符。尝试char a[5][10] = {0}; 5 个字符串,每个字符串最多 9 个字符,初始化为零。
  • 永远不要使用gets:这是一个非常糟糕的缺陷,它在C11之前被弃用,然后被禁止。
  • @Deduplicator 而scanf("%s", buf); 仍然存在

标签: c arrays char printf


【解决方案1】:

IMO 的 C 数组语法非常令人困惑 - 这与我通常阅读它的方式相反......而且看起来你也犯了这个错误。

您的数组有十个字符串槽,每个槽有 4 个字符(不是 5,因为 C 中的每个字符串都必须以 0 字符结尾)。因此,当您输入 peter 时,它不会舒适地放入 10 个字符的缓冲区,而是会溢出 5 个字符的缓冲区,从而节省了之前保存的一个字符。

如果没有 0 终止符,printf 将继续运行,因此也会写入其他名称。

【讨论】:

  • 相反?从左到右阅读,您会得到:char 元素名为 a,由 10 元素组成,每个元素又由 5 元素组成。 (不过答案很好。)
  • 我把它读作“5 的数组(10 的数组(字符))”,这在我看来是有道理的,因为当你索引它时,你拉下一层:a[0],对我来说, 是说取外部数组的第一个元素.... 这将是 5 的数组。 a[0][1] 只是继续它。如果您习惯于按照自己的方式阅读,从右到左可能听起来相反,但对我来说,这是阅读这段代码的自然方式,与函数和索引一致......当然,因为 C 将变量名后面的数组大小而不是其他类型(wtf?!),这两种方法都不起作用,因为中断很糟糕!
  • 评论空间用完了,但我的意思主要是 C 数组语法很糟糕。我几乎更喜欢其他任何东西:D 的 char[10][5] a; 以我喜欢的方式将所有内容分组......但是像 Go 的 a [5][10]char 这样的东西也是对 C 的改进。(我觉得 Go 完全落后,我发现它由于我根深蒂固的习惯,很难阅读,但至少该类型的中间没有名字!)
  • +1 用于提及 \0 终止符缺席和 printf 正在进行 :)
  • @AdamDRuppe 声明镜像使用... s[0] 是第一个字符串,s[1] 第二个字符串,s[2] 第三个字符串,对吗?所以(s[0])[9] 是第一个字符串中的第 10 个字符。正如buf[9]buf 中的第10 个字符一样。请记住,它是一个“数组数组”,即char s[5][10] 一个包含 5 个元素的数组,每个元素都是一个包含 10 个元素的数组。
【解决方案2】:

只需将您的 char a[10][5]; 更改为 char a[5][10];

然后,您将拥有 5 行,每行 10 列。 a 的当前设置允许您保存 10 个 4 个字符长的输入(因为您需要在字符串末尾有一个 \0 字符)。

C 不检查边界,多维数组连续存储在内存中。因此,输入超过 4 个字符时,您将溢出 char 数组的当前存储空间并写入下一行。

Adam D. Ruppe 提到 printf() 将在屏幕上打印字符,直到遇到 \0 终止符。看看你是:

  • 使用“peter”输入丢失终止符
  • 使用“david”输入丢失终止符

因此你得到输出“peterdavidalan”。现在我想你可以弄清楚“davidalan”输出的来源。

【讨论】:

  • 我的回答给出了更多解释,但这个答案很容易解决,让它工作!
  • 啊,是的,我在编辑我的帖子时没有看到你的答案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2020-03-23
相关资源
最近更新 更多