【问题标题】:Creating a user length defined array in C在 C 中创建用户长度定义的数组
【发布时间】:2017-12-03 22:02:47
【问题描述】:

我正在尝试创建一个具有可变起始长度的数组来获取字符串。代码应该计算单词并调整数组的大小,但这只是一个测试,我在这里公开它是因为我想知道这是一个好的做法还是一个错误。如果有什么我应该知道的,或者我必须记住的。

注意,我说的是 C,不是 C++

#include <stdio.h>
int main()
{       int c,b,count;
        scanf("%d",&c);
        count=c+1;
        getchar();
        char a[count];
        for ( c=b=0 ; c!=count && b!='\n' ; c++ )
        {
                b=getchar();
                a[c]=b;
        }
        a[c]='\0';
        printf("%s",a); printf("%d",c-1);
}

我不需要在执行时更改数组的大小。

我正在测试,我不记得为什么我第一次使用 c 变量而不是直接使用 count,但我记得第一个 getchar 是刷新缓冲区,因为它没有无需 getchar 即可工作。

我不知道为什么我需要放 getchar。如果我删除 getchar 程序将失败。

无论如何,该程序运行良好。第一次运行时,它需要一个带有 scanf 的数字,然后是文本。

如果文本大于数组的大小,程序将忽略它。

数字是数组的大小。

我的问题是:

a[variable] 做这项工作是个好习惯吗?

为什么我需要 getchar?

它将是便携式的吗?我的意思是,我不知道某些系统或标准是否像某些旧的 C 编译器一样不接受这一点。

有更好的方法吗?

【问题讨论】:

  • VLA 在 C99 中受支持,但在旧版 C 和 C++ 中均不支持,这使得您的代码非常难以移植,因此可能不是一个很好的做法。
  • 泰。我不知道 getchar 发生了什么
  • @goodvibration 现在距离 C99 已有 18 年了,这肯定是为每个人更新编译器的足够时间。其他语言无关
  • @goodvibration“非常不便携”?!这已经是 18 年的标准了。就好像您建议在 HTML 页面上使用 &lt;blink&gt; 以与 Netscape 2.0 兼容。 C和C++也是不同的语言。你建议哪种洋泾浜克里奥尔语?
  • 这个问题真的是关于getchar() 和数组无关(除了数组溢出的情况)

标签: c arrays


【解决方案1】:

做一个[变量]来做这个工作是个好习惯吗?

这取决于某人的编译器配置。 It has been supported since C99. 但是,由于没有充分的理由在这样一个简单的程序中使用它,请改用标准的mallocHere's an in-depth discussion of the topic.

为什么我需要 getchar?

您的终端中可能仍有一些输入缓冲,而第一个字符正在丢弃它。尝试将值打印到屏幕上,看看它是什么,这可能有助于弄清楚。

它会是便携式的吗?

请参阅我对您的第一个问题的回答。它可能适用于现代版本的 gcc,但例如它不适用于 Windows C(基本上仍然在 C89 上)。

【讨论】:

  • 说真的?!非标准扩展?!那么 ISO 和 ANSI 产生了什么?卫生纸?!
  • 对不起,这是一个错误,我已修复并澄清最新标准支持它。
  • 没有“最新标准”。只有一个标准。 C 编程语言。它只有一个有效的修订版,C11。其他所有已被撤销。诚然,VLA 现在是可选的,但 MSVC 现在也支持它们。
  • @AnttiHaapala 我再次澄清了我的答案,谢谢。默认情况下,MSVC 不支持 C 中的 VLA,您有启用它们的选项的参考吗?
  • 还有一个不会转换malloc的返回值。这个问题被标记在c,而不是c++
【解决方案2】:

做一个[变量]来做这个工作是个好习惯吗?

如果大小由任意用户输入确定而没有强加限制,则不是好的做法。用户可以轻松输入一个非常大的值并超出堆栈。

使用动态分配,或者检查输入值并将其强制到某个合理的限制。

另外值得注意的是,C++ 或某些 C 编译器不支持 VLA,因此代码缺乏可移植性。

为什么我需要 getchar?

用户必须至少输入 换行符scanf() 才能返回,但 %d 格式说明符不使用非数字字符,所以它保持缓冲。但是,您的代码很容易通过输入额外的非数字字符来破坏,例如 "16a&lt;newline&gt;" 会将 16 分配给 c,而 a 将被丢弃,而换行符像以前一样被缓冲。更好的解决方案是:

while( getchar() != `\n` ) {}

它将是便携式的吗?我的意思是,我不知道某些系统或标准是否像某些旧的 C 编译器一样不接受这一点。

C99 VLA 的采用是可变的,在 C11 中它们在任何情况下都是可选的。

有更好的方法吗?

我不敢说“更好”,但肯定是更安全、更灵活和更便携的方式。关于数组分配,可以使用malloc()

【讨论】:

    【解决方案3】:

    C 中使用malloccalloc 会是更好的选择

    https://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm

    【讨论】:

    • OP 提到他不想在运行时填充数组的大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多