如何使用fgets读取长度未知的输入 [英] How to read input of unknown length using fgets
问题描述
我应该如何使用fgets()
读取长输入,我不太明白.
How am I supposed to read long input using fgets()
, I don't quite get it.
我写了这个
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buffer[10];
char *input;
while (fgets(buffer,10,stdin)){
input = malloc(strlen(buffer)*sizeof(char));
strcpy(input,buffer);
}
printf("%s [%d]",input, (int)strlen(input));
free(input);
return 0;
}
推荐答案
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char buffer[10];
char *input = 0;
size_t cur_len = 0;
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
size_t buf_len = strlen(buffer);
char *extra = realloc(input, buf_len + cur_len + 1);
if (extra == 0)
break;
input = extra;
strcpy(input + cur_len, buffer);
cur_len += buf_len;
}
printf("%s [%d]", input, (int)strlen(input));
free(input);
return 0;
}
这是关于最少的更改集,这些更改将为您提供完整的输入行.每次最多增加9个字节的空间.那不是最好的方法,但是要做更好的方法(将分配的空间加倍,并记录分配的数量与使用的数量有关),这需要额外的簿记.请注意,cur_len
在input
所指向的空间中记录字符串的长度,但不包括终端空值.另请注意,使用extra
可以避免分配失败时发生内存泄漏.
This is about the minimal set of changes that will give you the complete line of input. This grows the space by up to 9 bytes at a time; that isn't the best way to do it, but there's extra bookkeeping involved doing it the better ways (doubling the space allocated, and keeping a record of how much is allocated vs how much is in use). Note that cur_len
record the length of the string in the space pointed to by input
excluding the terminal null. Also note that the use of extra
avoids a memory leak on failure to allocate.
strcpy()
操作可以合法地替换为memmove(input + cur_len, buffer, buf_len + 1)
(在这种情况下,您可以使用memcpy()
而不是memmove()
,但是它并不总是有效,而memmove()
总是可以正常工作,因此使用memmove()
更为可靠.
The strcpy()
operation could be legitimately replaced by memmove(input + cur_len, buffer, buf_len + 1)
(and in this context, you could use memcpy()
instead of memmove()
, but it doesn't always work while memmove()
does always work, so it is more reliable to use memmove()
).
具有加倍长度— cur_max
变量记录分配了多少空间,而cur_len
记录正在使用的空间.
With length-doubling — the cur_max
variable records how much space is allocated, and cur_len
records how much space is in use.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char buffer[10];
char *input = 0;
size_t cur_len = 0;
size_t cur_max = 0;
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
size_t buf_len = strlen(buffer);
if (cur_len + buf_len + 1 > cur_max)
{
size_t new_len = cur_max * 2 + 1;
if (buf_len + 1 > new_len)
new_len = buf_len + 1;
char *extra = realloc(input, new_len);
if (extra == 0)
break;
input = extra;
cur_max = new_len;
}
strcpy(input + cur_len, buffer);
cur_len += buf_len;
}
printf("%s [%d]", input, (int)strlen(input));
free(input);
return 0;
}
这篇关于如何使用fgets读取长度未知的输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!