I'm learning C programming and I have to implement a program that read an input string of of unknown size. I wrote this code:
我正在学习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] = '\0';
printf("Input string: %s\n", string);
free(string);
return 0;
}
But the last printf
doesn't show the whole string but only the last char. So if I enter hello, world
the last printf
prints d
.
但是最后的printf没有显示整个字符串,只有最后一个字符。如果我输入hello,最后一个printf打印d。
After a little research I tried this code and it works! But I don't get the difference with mine.
在做了一些研究之后,我尝试了这个代码,它确实有效!但是我和我的不一样。
I hope I made myself clear, thank you for your attention.
我希望我讲的很清楚,谢谢大家的关注。
4 个解决方案
#1
3
There are several problems with your code:
你的代码有几个问题:
- you store all characters into the first byte of allocated memory
- 将所有字符存储到分配内存的第一个字节中
- you read characters into a
char
variable, you cannot correctly test forEOF
. - 将字符读入char变量中,不能正确地测试EOF。
- you will run an infinite loop, allocating all available memory and finally crash if standard input does not contain a
'\n'
, such as redirecting from an empty file. - 您将运行一个无限循环,分配所有可用内存,如果标准输入不包含“\n”,例如从空文件重定向,则最终崩溃。
- less important, you reallocate the buffer for each byte read, inefficient but can be optimized later.
- 不太重要的是,您可以重新分配每个字节读取的缓冲区,效率不高,但是可以稍后进行优化。
Here is a corrected version:
这里有一个修正版:
#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] = '\0';
printf("Input string: %s\n", string);
free(string);
return 0;
}
Regarding your question about the difference with the linked code, it uses the same method, has one less bug but also one more bug:
关于你关于链接代码的区别的问题,它使用了相同的方法,有一个bug少了一个bug,但也多了一个bug:
- it stores the character in the appropriate offset in
str
. - 它将字符存储在str中适当的偏移量中。
- it runs an infinite loop if the input file does not contain a
'\n'
, same as yours. - 如果输入文件不包含“\n”,则运行一个无限循环。
- it invokes undefined behavior because
c
is not initialized for first test. - 它调用未定义的行为,因为c没有为第一次测试初始化。
#2
5
In your version of the code you assign the newly read character, c
, to string
, using:
在您的代码版本中,您将新读取的字符c分配给string,使用:
*string = c;
*string
points at the beginning of the string so you keep replacing the first character of string with the newly read character.
*字符串点在字符串的开头,所以您要不断地用新读的字符替换字符串的第一个字符。
The code you linked to does the following:
您所链接的代码如下:
str[i] = c
Basically, it is assigning the character to the end of the string, using the index i
.
基本上,它使用索引i将字符分配到字符串的末尾。
In your version of the code you could use size - 1
instead of i
.
在您的版本的代码中,您可以使用size - 1而不是i。
#3
3
Try changing:
试着改变:
*string = c;
To:
:
string[size-1] = c;
That way you won't just overwrite the first character each time.
这样就不会每次都覆盖第一个字符。
#4
1
try
试一试
*(string + size - 1) = c;
maybe this helps
也许这可以帮助
#1
3
There are several problems with your code:
你的代码有几个问题:
- you store all characters into the first byte of allocated memory
- 将所有字符存储到分配内存的第一个字节中
- you read characters into a
char
variable, you cannot correctly test forEOF
. - 将字符读入char变量中,不能正确地测试EOF。
- you will run an infinite loop, allocating all available memory and finally crash if standard input does not contain a
'\n'
, such as redirecting from an empty file. - 您将运行一个无限循环,分配所有可用内存,如果标准输入不包含“\n”,例如从空文件重定向,则最终崩溃。
- less important, you reallocate the buffer for each byte read, inefficient but can be optimized later.
- 不太重要的是,您可以重新分配每个字节读取的缓冲区,效率不高,但是可以稍后进行优化。
Here is a corrected version:
这里有一个修正版:
#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] = '\0';
printf("Input string: %s\n", string);
free(string);
return 0;
}
Regarding your question about the difference with the linked code, it uses the same method, has one less bug but also one more bug:
关于你关于链接代码的区别的问题,它使用了相同的方法,有一个bug少了一个bug,但也多了一个bug:
- it stores the character in the appropriate offset in
str
. - 它将字符存储在str中适当的偏移量中。
- it runs an infinite loop if the input file does not contain a
'\n'
, same as yours. - 如果输入文件不包含“\n”,则运行一个无限循环。
- it invokes undefined behavior because
c
is not initialized for first test. - 它调用未定义的行为,因为c没有为第一次测试初始化。
#2
5
In your version of the code you assign the newly read character, c
, to string
, using:
在您的代码版本中,您将新读取的字符c分配给string,使用:
*string = c;
*string
points at the beginning of the string so you keep replacing the first character of string with the newly read character.
*字符串点在字符串的开头,所以您要不断地用新读的字符替换字符串的第一个字符。
The code you linked to does the following:
您所链接的代码如下:
str[i] = c
Basically, it is assigning the character to the end of the string, using the index i
.
基本上,它使用索引i将字符分配到字符串的末尾。
In your version of the code you could use size - 1
instead of i
.
在您的版本的代码中,您可以使用size - 1而不是i。
#3
3
Try changing:
试着改变:
*string = c;
To:
:
string[size-1] = c;
That way you won't just overwrite the first character each time.
这样就不会每次都覆盖第一个字符。
#4
1
try
试一试
*(string + size - 1) = c;
maybe this helps
也许这可以帮助