#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()
).
С длиной удвоением - в 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;
}
Посмотрите на 'realloc'. И рассмотрите стратегию удвоения распределения каждый раз, а также прямое считывание в буфер. BTW: Формат printf для 'size_t' -'% zu'. – Deduplicator
Если у вас есть это, рассмотрите возможность использования '' getline' '(http://linux.die.net/man/3/getline) вместо 'fgets'. – 5gon12eder
Я знаю о getline, но я должен использовать fgets – lllook