这两种在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
没有为第一次测试初始化。
我正在学习 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
没有为第一次测试初始化。