Я изучаю программирование на C, и мне нужно реализовать программу, которая считывает входную строку неизвестного размера. Я написал такой код:

int main() {
    char *string;
    char c;
    int size = 1;

    string = (char*)malloc(sizeof(char));

    if (string == NULL) {
        printf("Error.\n");
        return -1;
    }
    printf("Enter a string:");
    while ((c = getchar()) != '\n') {
        *string = c;
        string = (char*)realloc(string, sizeof(char) * (size + 1));
        size++;
    }
    string[size - 1] = '\0';

    printf("Input string: %s\n", string);

    free(string);
    return 0;
}

Но последний printf показывает не всю строку, а только последний символ. Поэтому, если я введу hello, world, последний printf напечатает d.

После небольшого исследования я попробовал этот код, и он работает! Но я не понимаю разницы со своим.

Надеюсь, я ясно выразился, спасибо за внимание.

3
Ker 4 Янв 2016 в 05:51

4 ответа

Лучший ответ

С вашим кодом есть несколько проблем:

  • вы сохраняете все символы в первый байт выделенной памяти
  • вы считываете символы в переменную char, вы не можете правильно проверить EOF.
  • вы запустите бесконечный цикл, выделив всю доступную память и, наконец, завершите работу, если стандартный ввод не содержит '\n', например, перенаправление из пустого файла.
  • менее важно, вы перераспределяете буфер для каждого чтения байта, что неэффективно, но может быть оптимизировано позже.

Вот исправленная версия:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char *string;
    int c;
    int len = 0;

    string = malloc(1);
    if (string == NULL) {
         printf("Error.\n");
         return -1;
    }
    printf("Enter a string:");
    while ((c = getchar()) != EOF && c != '\n') {
        string[len++] = c;
        string = realloc(string, len + 1);
        if (string == NULL) {
            printf("cannot allocate %d bytes\n", len + 1);
            return -1;
        }
    }
    string[len] = '\0';

    printf("Input string: %s\n", string);
    free(string);
    return 0;
}

Что касается вашего вопроса о разнице со связанным кодом, он использует тот же метод, имеет на одну ошибку меньше, но также еще одну ошибку:

  • он сохраняет символ в соответствующем смещении в str.
  • он запускает бесконечный цикл, если входной файл не содержит '\n', такого же, как ваш.
  • он вызывает неопределенное поведение, потому что c не инициализирован для первого теста.
3
chqrlie 4 Янв 2016 в 03:28

Пытаться

*(string + size - 1) = c;

Может это поможет

1
kaitian521 4 Янв 2016 в 02:56

В вашей версии кода вы назначаете новый прочитанный символ, c, string, используя:

*string = c;

*string указывает на начало строки, поэтому вы продолжаете заменять первый символ строки новым прочитанным символом.

Код, на который вы ссылаетесь, делает следующее:

str[i] = c

По сути, он присваивает символ концу строки с помощью индекса i.

В вашей версии кода вы можете использовать size - 1 вместо i.

5
mttrb 4 Янв 2016 в 02:56

Попробуйте изменить:

*string = c;

Кому:

string[size-1] = c;

Таким образом, вы не будете каждый раз просто перезаписывать первый символ.

3
Tom Karzes 4 Янв 2016 в 02:56