@pepl213

Как выделить память для строки неизвестной длины?

Нужно считать из stdin строку (заканчивается \n),длина которой неизвестна.
Т.е. может быть
agdadsgasdfasdf
Или
asjdfhkasljdfhasd.....
Я попытался сделать что-то такое, но получается, что, когда я получаю новый символ, массив chars переопределяется.
#include <stdio.h>
#include <malloc.h>


int main(){
	char *chars;
	int c,n=0;
	while((c=getchar()) != '\n'){
		chars = (char*)malloc(++n * sizeof(char));
		chars[n-1] = c;
	}
	printf("%s\n", chars);
}
  • Вопрос задан
  • 2026 просмотров
Пригласить эксперта
Ответы на вопрос 2
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Как это усовершенствовать?


Из man scanf:
An optional 'm' character. This is used with string conversions (%s, %c, %[), and relieves the caller of the need to allocate a corresponding buffer to hold the input: instead, scanf() allocates a buffer of sufficient size, and assigns the address of this buffer to the corresponding pointer argument, which should be a pointer to a char * variable (this variable does not need to be initialized before the call). The caller should subsequently free(3) this buffer when it is no longer required.

Т.е.:
#include <stdio.h>

int main()
{
  char *chars;
  scanf("%m[^\n]",&chars);
  printf("%s\n", chars);
}
Ответ написан
Комментировать
sergey-gornostaev
@sergey-gornostaev Куратор тега C
Седой и строгий
const unsigned int MAX_LENGTH = 1 * 1024 * 1024;  // Не выделять больше мегабайта памяти
const unsigned int CHUNK_SIZE = 1024;             // Выделять блоками по килобайту

int main() {
    unsigned int str_len = CHUNK_SIZE;
    char *str_ptr = malloc(CHUNK_SIZE);           // Выделяем первый килобайтный блок

    if (str_ptr == NULL)
        err(EXIT_FAILURE, "Не удалось выделить память!\n");

    int c;
    unsigned int i;
    for (i = 0, c = EOF; (c = getchar()) != '\n' && c != EOF; i++) {
        str_ptr[i] = c;

        if (i == MAX_LENGTH) {
            free(str_ptr);
            err(EXIT_FAILURE, "Слишком много входных данных!\n");
        }
        
        if (i == str_len) {                       // Блок заполнен
            str_len = i + CHUNK_SIZE;
            str_ptr = realloc(str_ptr, str_len);  // Расширяем блок на ещё один килобайт
        }
    }
    str_ptr[i] = '\0';                            // Признак конца строки

    printf("%s\n", str_ptr);

    free(str_ptr);
    str_ptr = NULL;

    return EXIT_SUCCESS;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы