在一个uni作业中,我必须捕获一个字符串(以后会是一个命令)。老师建议使用fgets,但由于我不知道限制,我决定使用scanf。
问题是,它的priting不对。
这是我的测试代码。
int main()
{
char *name1;
printf("go:");
scanf(" %[^\n]", name1);
printf("%s xx %s", name1);
}
如果你有任何关于fgets的建议,那就太好了!
如果你是为PC编程(而不是为一些嵌入式设备),只需分配一个 真正的大缓冲区 (例如,1 MB,或10,或100),你确信它能满足所有可以想象的使用情况。现在的内存是非常便宜的,为了节省内存而花费资源和复杂的程序是不值得的。举个例子。你需要多长时间才能100%确定 David的解决方案完全没有错误?I 可能 如果在生产代码中使用的话,我想为它写一个测试)。)
不过要动态或静态分配内存,自动变量的堆栈空间可能还是有限的。然后使用fgets。不过,一定要优雅地处理过长的行。没有必要像David的答案那样,将它们从分块中连接起来。这些长行要么是测试用例,要么是数据错误。你可以简单地用错误信息退出。如果你想满足David Ranieri的良好秩序感和原则,你也可以显式地释放任何分配的内存,尽管在PC上这完全是多余的)。
在标准的C库中,没有任何函数可以安全地读取一个无边界的字符串。这是我亲手写的一个函数(不能保证它有所有的安全功能,我试着加入了我想到的东西)。
#include <stdio.h>
#include <stdlib.h>
char* get_string(FILE* stream)
{
#define INITIAL_BUF_SIZE 100
size_t size = INITIAL_BUF_SIZE, i = 0;
int c;
char* s = malloc(size * sizeof *s);
if (s == NULL)
return NULL;
while ((c = getc(stream)) != '\n' && c != EOF)
{
s[i++] = c;
if (i == size)
{
size *= 2;
char* p = realloc(s, size * sizeof *p);
if (p == NULL)
{
free(s);
return NULL;
}
s = p;
}
}
s[i++] = '\0';
if (i == size)
return s;
char* p = realloc(s, i * sizeof *p);
if (p == NULL)
{
free(s);
return NULL;
}
return p;
#undef INITIAL_BUF_SIZE
}
int main(void)
{
char* name1 = get_string(stdin);
printf("The string is: %s\n", name1);
free(name1);
}
请注意,返回的字符串必须由调用者使用 free()
以避免内存泄漏。