#c #malloc #realloc
#c #malloc #перераспределение
Вопрос:
Я хотел написать программу на C, которая будет принимать строку любой длины из stdin
и отображать ее или применять любую функцию к этой строке. Для этого мне понадобится строка ( char []
) с динамической длиной.
Вот как я это сделал:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
char *line;
line = malloc(10);
line[0] = '';
char *str = malloc(10);
fprintf(stdout, "Please enter your line:n");
while(fgets(str, 10, stdin)){
//check for line break
if(str[strlen(str)-1] == 'n'){
str[strlen(str) - 1] = '';
strcat(line, str);
break;
}
strcat(line, str);
line = realloc(line, strlen(line) 10);
str = realloc(str, strlen(str) 10);
}
fprintf(stderr, "you entered %sn", line);
//just for testing
/*
fprintf(stderr, "n str= %s n", str );
fprintf(stderr, "n line= %s n", line);
*/
free(line);
free(str);
exit(EXIT_SUCCESS);
}
Однако это выглядит ужасно. Мне нужны два массива символов. В char *str
я запишу входные данные из stdin и объединю их в char *line
. str
будет содержать только до 10 байт символов, и из-за этого мне нужно объединить все в line
.
Есть ли более чистый способ сохранить выходные данные из stdin
в этом случае и применить к нему какую-либо функцию? Я делаю это неправильно? Можно ли это сделать без malloc
и realloc
?
Комментарии:
1. Вам не нужно
realloc(str)
, вы никогда не читаете более 10 байт за раз, вы можете просто определитьstr
какchar str[10]
.2. И тогда вы создали довольно типичную функцию C. Обычно вы бы сделали
str
степень 2, например1024
, илиBUFSIZE
потому что процессор такой.3. «будет принимать строку любой длины из stdin» -> как насчет чего-то более устойчивого к хакерской эксплуатации, например «будет принимать строку любой длины из stdin до 1 Мбайт»?
4. @chux Реализация библиотеки C и / или ядро уже справятся с этим за вас. Если кто-либо попытается ввести чрезвычайно длинную строку, процесс будет остановлен из-за ошибки нехватки памяти (
realloc
вернетсяNULL
).5. Ничего ужасного в этом нет. В C вы должны управлять своей собственной памятью. Если вы не знаете, сколько вам нужно до времени выполнения, вы должны динамически распределять его по мере необходимости. Вы также должны проверить возвращаемые значения
malloc
иrealloc
на случай, если они не будут выполнены.
Ответ №1:
Это пример. Вам нужно добавить проверку результатов malloc amp; realloc (я не делал этого для простоты)
#include <stdio.h>
#include <stdlib.h>
#define CHUNK 32
char *readline(void)
{
size_t csize = CHUNK;
size_t cpos = 0;
char *str = malloc(CHUNK);
int ch;
while((ch = fgetc(stdin)) != 'n' amp;amp; ch != 'r')
{
str[cpos ] = ch;
if(cpos == csize)
{
csize = CHUNK;
str = realloc(str, csize);
}
}
str[cpos] = 0;
return str;
}
int main()
{
printf("n%sn", readline());
return 0;
}
рабочий пример:https://onlinegdb.com/Sk9r4gOYV
Вы также должны освободить выделенную память, когда она больше не нужна.