[英]Reading arbitrary length strings in C
I've attempted to write a C program to read a string and display it back to the user.我试图编写一个 C 程序来读取字符串并将其显示给用户。 I've tested it with a lot of input and it seems to work properly.
我已经用大量输入对其进行了测试,它似乎工作正常。 The thing is that I'm not sure whether or not the
c != EOF
condition is necessary inside the while expression, and since by definition, the size of a char is 1 byte, maybe I can remove the sizeof(char)
expressions inside the malloc
and realloc
statements, but I'm not sure about this.问题是我不确定
c != EOF
条件是否在 while 表达式中是必需的,因为根据定义,char 的大小是 1 字节,也许我可以删除里面的sizeof(char)
表达式malloc
和realloc
语句,但我不确定这一点。
Here's the program, also, I manually added a null terminating character to the string:这是程序,我也手动在字符串中添加了一个 null 终止字符:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *str = malloc(sizeof(char));
if (!str)
return 1;
char c;
char *reallocStr;
size_t len = 0;
size_t buf = 1;
printf("Enter some text: ");
while ((c = getchar()) != '\n' && c != EOF) {
if (len == buf) {
buf *= 2;
reallocStr = realloc(str, buf * sizeof(char));
if (!reallocStr)
return 1;
str = reallocStr;
}
str[len++] = c;
}
str[len] = '\0';
printf("You entered: %s\n", str);
free(str);
return 0;
}
As mentioned in the comments, you have a buffer overflow in your code, so you would need to fix that at the very least.如评论中所述,您的代码中有缓冲区溢出,因此您至少需要修复它。 To answer your specific questions,
sizeof(char)
is guaranteed to be 1 (dictated by the c99 spec), so you don't need to multiply by sizeof(char)
.要回答您的具体问题,
sizeof(char)
保证为 1(由 c99 规范规定),因此您无需乘以sizeof(char)
。 It's good practice to check for EOF
as if your input is coming from an alternate source that has no newline, you don't die (so if someone for example did printf %s hello | yourprogram
from a bash prompt, you wouldn't die).检查
EOF
是一种很好的做法,就好像您的输入来自没有换行符的备用源一样,您不会死(例如,如果有人做了printf %s hello | yourprogram
来自 bash 提示,您不会死)。
Problems include问题包括
Buffer overflow缓冲区溢出
Incorrect type类型不正确
getchar()
reruns an int
with the values [0..UCHAR_MAX] and the negative: EOF
. getchar()
使用值 [0..UCHAR_MAX] 和负值重新运行int
: EOF
。 These 257 different values lose distinctiveness when saved as a char
.这 257 个不同的值在保存为
char
时会失去独特性。 Possible outcomes: infinite loop or premature loop end.可能的结果:无限循环或过早的循环结束。 Instead:
反而:
// char c;
int c;
Advanced: Arbitrary length进阶:任意长度
For very long lines buf *= 2;
对于很长的行
buf *= 2;
overflows when buf
is SIZE_MAX/2 + 1
.当
buf
为SIZE_MAX/2 + 1
时溢出。 An alterative to growing in steps of 1, 2, 4, 8, 16,..., consider 1, 3, 7, 15, .... That way code can handle strings up to SIZE_MAX
.以 1, 2, 4, 8, 16,... 的步长增长的替代方法,考虑 1, 3, 7, 15, .... 这样代码可以处理高达
SIZE_MAX
的字符串。
Advanced: Reading '\0'
高级:读取
'\0'
Although uncommon, possible to read in a null character .虽然不常见,但可以在null 字符中读取。 Then
printf("You entered: %s\n", str);
然后
printf("You entered: %s\n", str);
will only print to that null character and not to the end of input.只会打印到该null 字符而不是输入的末尾。
To print all, take advantage that code knows the length.要全部打印,请利用代码知道长度的优势。
printf("You entered: ");
fwrite(str, len, 1, stdout);
printf("\n");
To be clear, text input here is not reading of strings , but of reading of lines .需要明确的是,这里的文本输入不是读取字符串,而是读取行。 That input is saved and converted to a string by appending a null character .
该输入通过附加null 字符被保存并转换为字符串。 Reading a
'\0'
complicates things, but something robust code handles.读取
'\0'
会使事情复杂化,但可以处理一些健壮的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.