我试图从用户那里获取一个表达式并将其放入动态创建的字符串中。代码如下:
char *get_exp() {
char *exp, *tmp = NULL;
size_t size = 0;
char c;
scanf("%c", &c);
while (c != EOF && c != '\n') {
tmp = realloc(exp, ++size * sizeof char);
if (tmp == NULL)
return NULL;
exp = tmp;
exp[size-1] = c;
scanf("%c", &c);
}
tmp = realloc(exp, size+1 * sizeof char);
size++;
exp = tmp;
exp[size] = '\0';
return exp;
}
但是,由于某种原因,每次读取的第一个字符都是换行符,因此 while 循环退出。我正在使用 XCode,这可能是问题的原因吗?
最佳答案
不,XCode 不是你的问题的一部分(这是一个可怜的 worker 责怪他的工具)。
您尚未初始化 exp
,这会导致问题。
您检测 EOF 的代码已完全损坏;您必须测试 scanf()
的返回值来检测 EOF。您最好将 getchar()
与 int c
一起使用:
int c;
while ((c = getchar()) != EOF && c != '\n')
{
...
}
如果您觉得必须使用 scanf()
,那么您需要测试对 scanf()
的每次调用:
char c;
while (scanf("%c", &c) == 1 && c != EOF)
{
...
}
您确实在循环中检查了realloc()
的结果;那挺好的。您不会在循环后检查 realloc()
的结果(并且您不会缩小分配);请每次检查。
您应该考虑使用一种一次分配多个字节的机制,而不是每个读取的字符一个realloc()
;那很贵。
当然,如果目标只是读取一行,那么使用 POSIX getline()
是最简单的。 ,它为您处理所有分配。或者,您可以使用
fgets()
读取该行。您可以使用固定缓冲区来收集数据,然后将其复制到适当大小的动态分配的缓冲区。您还需要考虑该行很长的可能性,因此您需要检查是否确实获得了换行符。
关于c - 动态创建的C字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20032349/