【问题标题】:Why does it print random symbols when exceeding 44 characters为什么超过44个字符时打印随机符号
【发布时间】:2014-12-26 21:24:04
【问题描述】:

我正在从一本书 C 编程:现代方法中学习 C。现在我正在练习关于数组的低谷练习。其中一个练习是编写一个以不同方式打印输入消息的过滤器。

到目前为止(参见下面的代码),一切正常,直到字符数超过 44,然后它会打印随机符号。如果字符数低于 44,则一切正常。我完全不知道为什么会这样。问题出在哪里,有什么解决办法?

int i = 0, k = 0;
char message[k],ch;

printf("Enter a message: ");
while(toupper(ch = getchar()) != '\n')
{
    message[k] = ch;
    k++;
}
printf("In B1FF-speak: ");
for (i = 0; i <= k - 1; i++)
{
    switch(toupper(message[i]))
    {
        case 'A':
            printf("4");
            break;
        case 'B':
            printf("8");
            break;
        case 'E':
            printf("3");
            break;
        case 'I':
            printf("1");
            break;
        case 'O':
            printf("0");
            break;
        case 'S':
            printf("5");
            break;
        default:
            printf("%c", toupper(message[i]));
            break;
    }
}

【问题讨论】:

  • char message[k] k 设置为 0?这是一个严肃的问题吗???
  • @lurker: char message[k] 其中k==0 具有未定义的行为。
  • @barakmanos:OP 显然假设更改 k 的值会更改数组的长度。这不是一个完全不合理的假设。它恰好是不正确的。
  • @KeithThompson 好的,知道了。但在这两种情况下都是一个坏主意。
  • @KeithThompson:是的,我现在明白了。有时,了解受试者的思维方式以解释其问题所在,这本身就是一项具有挑战性的任务(您似乎已经处理得很好)。我想太多年的编程使我能够“超越界限”看到其他感知(在这种特定情况下的自然感知,如果我可以补充的话,现在我明白了你的观点) - 有点生硬。 P.S.:有趣的是,显而易见的事情有时却让你不知所措

标签: c arrays


【解决方案1】:
int i = 0, k = 0;
char message[k],ch;

您已将message 定义为可变长度数组 (VLA)。 (这是 1990 版本的 C 中不存在的功能;它是由 1999 标准添加的,并在 2011 标准中成为可选的。)

由于k的值为0,所以message的长度为0。 C 不支持零长度数组。定义一个恒定长度为零的数组是非法的(违反约束,需要诊断)。定义长度为零的可变长度数组具有未定义的行为。

VLA 的长度在定义时是固定的。稍后更改 k 的值不会更改数组的长度。您的代码似乎假设它会。

您的程序似乎可以在最长为 44 的情况下工作。这就是未定义行为的本质。可能发生的最糟糕的事情是你的程序似乎“正常”工作;这只是意味着您有一个难以检测的错误。

如果您想在一个数组中存储任意数量的元素,您可以首先将其定义为足够大的大小(很难或不可能确定它必须有多大),或者您可以使用realloc() 动态分配数组并根据需要扩展它。 (realloc() 实际上并没有扩展数组;它创建了一个更大的新数组,并将旧数组的内容复制到新数组中。如果可用内存不足,它可能会失败;请始终检查它返回的值以确定它是成功还是失败。)

【讨论】:

    猜你喜欢
    • 2014-12-17
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2021-03-14
    • 2020-01-16
    • 1970-01-01
    • 2016-03-21
    • 2021-12-15
    相关资源
    最近更新 更多