Подтвердить что ты не робот

Как читать строку с клавиатуры, используя C?

Я хочу прочитать строку, введенную пользователем. Я не знаю длину строки. Поскольку в C нет строк, я объявил указатель:

char * word;

и использовать scanf для чтения ввода с клавиатуры:

scanf("%s" , word) ;

но я получил ошибку сегментации.

Как я могу прочитать ввод с клавиатуры на C, когда длина неизвестна?

4b9b3361

Ответ 1

У вас нет хранилища, выделенного для word - это просто висящий указатель.

Изменить:

char * word;

в

char word[256];

Обратите внимание, что 256 - произвольный выбор здесь - размер этого буфера должен быть больше, чем самая большая возможная строка, с которой вы можете столкнуться.

Обратите внимание, что fgets является лучшим (безопасным) вариантом, чем scanf для чтения строк произвольной длины, поскольку он принимает аргумент size, что, в свою очередь, помогает предотвратить переполнение буфера:

 fgets(word, sizeof(word), stdin);

Ответ 2

Я не понимаю, почему существует рекомендация использовать scanf() здесь. scanf() безопасен, только если вы добавите параметры ограничения в строку формата - например, %64s или так.

Лучше всего использовать char * fgets ( char * str, int num, FILE * stream );.

int main()
{
    char data[64];
    if (fgets(data, sizeof data, stdin)) {
        // input has worked, do something with data
    }
}

(непроверенные)

Ответ 3

При чтении ввода из любого файла (включая stdin), где вы не знаете длину, часто лучше использовать getline, а не scanf или fgets, потому что getline будет обрабатывать выделение памяти для вашей строки автоматически, пока вы предоставляете нулевой указатель для получения введенной строки. Этот пример иллюстрирует:

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

int main (int argc, char *argv[]) {

    char *line = NULL;  /* forces getline to allocate with malloc */
    size_t len = 0;     /* ignored when line = NULL */
    ssize_t read;

    printf ("\nEnter string below [ctrl + d] to quit\n");

    while ((read = getline(&line, &len, stdin)) != -1) {

        if (read > 0)
            printf ("\n  read %zd chars from stdin, allocated %zd bytes for line : %s\n", read, len, line);

        printf ("Enter string below [ctrl + d] to quit\n");
    }

    free (line);  /* free memory allocated by getline */

    return 0;
}

Соответствующие части:

char *line = NULL;  /* forces getline to allocate with malloc */
size_t len = 0;     /* ignored when line = NULL */
/* snip */
read = getline (&line, &len, stdin);

Настройка line на NULL заставляет getline автоматически выделять память. Пример вывода:

$ ./getline_example

Enter string below [ctrl + d] to quit
A short string to test getline!

  read 32 chars from stdin, allocated 120 bytes for line : A short string to test getline!

Enter string below [ctrl + d] to quit
A little bit longer string to show that getline will allocated again without resetting line = NULL

  read 99 chars from stdin, allocated 120 bytes for line : A little bit longer string to show that getline will allocated again without resetting line = NULL

Enter string below [ctrl + d] to quit

Итак, с getline вам не нужно угадывать, как долго будет ваша пользовательская строка.

Ответ 4

#include<stdio.h>

int main()
{
    char str[100];
    scanf("%[^\n]s",str);
    printf("%s",str);
    return 0;
}

вход: читать строку
ouput: вывести строку

Этот код печатает строку с пробелами, как показано выше.

Ответ 5

Вам нужно, чтобы указатель указывал где-то его использовать.

Попробуйте этот код:

char word[64];
scanf("%s", word);

Это создает массив символов lenth 64 и читает ввод к нему. Обратите внимание, что если вход длиннее 64 байтов, массив слов переполняется, и ваша программа становится ненадежной.

Как указал Йенс, было бы лучше не использовать scanf для чтения строк. Это было бы безопасным решением.

char word[64]
fgets(word, 63, stdin);
word[63] = 0;