这两种在C中获取字符串输入的方法有什么区别?

What is the difference between these two methods to get string input in C?

我正在学习 C 编程,我必须实现一个程序来读取未知大小的输入字符串。 我写了这段代码:

int main() {
    char *string;
    char c;
    int size = 1;

    string = (char*)malloc(sizeof(char));

    if (string == NULL) {
        printf("Error.\n");
        return -1;
    }
    printf("Enter a string:");
    while ((c = getchar()) != '\n') {
        *string = c;
        string = (char*)realloc(string, sizeof(char) * (size + 1));
        size++;
    }
    string[size - 1] = '[=10=]';

    printf("Input string: %s\n", string);

    free(string);
    return 0;
}

但是最后一个 printf 不显示整个字符串,只显示最后一个字符。 所以如果我输入 hello, world 最后一个 printf 打印 d.

经过一些研究后,我尝试了 this 代码,它成功了!但是我没看出来和我的有什么区别。

希望我说清楚了,谢谢您的关注。

在您的代码版本中,您将新读取的字符 c 分配给 string,使用:

*string = c;

*string 指向字符串的开头,因此您不断用新读取的字符替换字符串的第一个字符。

您链接到的代码执行以下操作:

str[i] = c

基本上,它是将字符分配到字符串的末尾,使用索引i

在您的代码版本中,您可以使用 size - 1 而不是 i

尝试更改:

*string = c;

收件人:

string[size-1] = c;

这样你就不会每次都覆盖第一个字符。

尝试

*(string + size - 1) = c;

也许这有帮助

你的代码有几个问题:

  • 您将所有字符存储到已分配内存的第一个字节中
  • 您将字符读入 char 变量,无法正确测试 EOF
  • 你将 运行 无限循环,分配所有可用内存,如果标准输入不包含 '\n',最终会崩溃,例如从空文件重定向。
  • 不太重要,您为每个读取的字节重新分配缓冲区,效率低下但可以稍后优化。

这是更正后的版本:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char *string;
    int c;
    int len = 0;

    string = malloc(1);
    if (string == NULL) {
         printf("Error.\n");
         return -1;
    }
    printf("Enter a string:");
    while ((c = getchar()) != EOF && c != '\n') {
        string[len++] = c;
        string = realloc(string, len + 1);
        if (string == NULL) {
            printf("cannot allocate %d bytes\n", len + 1);
            return -1;
        }
    }
    string[len] = '[=10=]';

    printf("Input string: %s\n", string);
    free(string);
    return 0;
}

关于你问的和链接代码的区别,用的是一样的方法,少了一个BUG,也多了一个BUG:

  • 它将字符存储在 str 中适当的偏移量中。
  • 如果输入文件不包含 '\n',它 运行 是一个无限循环,与您的一样。
  • 它调用未定义的行为,因为 c 没有为第一次测试初始化​​。