[英]How to read input of unknown length using fgets
我怎么应该使用fgets()
读取长输入,我不太明白。
我写了这个
#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
指向的空间中的字符串长度,不包括终端null。 另请注意,使用extra
可避免因分配失败而导致内存泄漏。
strcpy()
操作可以合法地替换为memmove(input + cur_len, buffer, buf_len + 1)
(在这种情况下,你可以使用memcpy()
而不是memmove()
,但是当memmove()
它并不总是有效memmove()
总是有效,因此使用memmove()
更可靠。
通过长度加倍 - cur_max
变量记录分配了多少空间, cur_len
记录了正在使用的空间。
#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;
}
更好的方法是使用将为您分配的输入机制,例如getline
(甚至是scanf
)。 ( 注意: scanf
不会在所有编译器中分配。它在gcc/Linux
,但不在Windows/Codeblocks/gcc
)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *input;
scanf ("%m[^\n]%*c", &input);
printf("\n %s [%d]\n\n",input, (int)strlen(input));
free(input);
return 0;
}
输出:
$ ./bin/scanfinput
This is my longer string.
This is my longer string. [25]
getline示例
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *input = NULL; /* input buffer, NULL forces getline to allocate */
size_t n = 0; /* maximum characters to read (0 - no limit */
ssize_t nchr = 0; /* number of characters actually read */
if ((nchr = getline (&input, &n, stdin)) != -1)
input[--nchr] = 0; /* strip newline */
printf ("\n %s [%zd]\n\n", input, nchr);
free(input);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.