Как читать строку с клавиатуры, используя C?
Я хочу прочитать строку, введенную пользователем. Я не знаю длину строки. Поскольку в C нет строк, я объявил указатель:
char * word;
и использовать scanf
для чтения ввода с клавиатуры:
scanf("%s" , word) ;
но я получил ошибку сегментации.
Как я могу прочитать ввод с клавиатуры на C, когда длина неизвестна?
Ответы
Ответ 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;