C массив символов динамической длины

#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

Вы также должны освободить выделенную память, когда она больше не нужна.