как читать сканф с пробелами - PullRequest
2 голосов
/ 27 апреля 2010

У меня странная проблема

я пытаюсь прочитать строку из консоли с помощью scanf ()

как это

scanf("%[^\n]",string1);

но ничего не читает. он просто пропускает весь сканф.

Я пытаюсь это сделать в компиляторе GCC

Ответы [ 4 ]

5 голосов
/ 27 апреля 2010

Попытка использовать scanf для чтения строк с пробелами может привести к ненужным проблемам с переполнением буфера и появлением случайных строк, оставшихся во входном буфере для последующего чтения. gets() часто предлагается в качестве решения этой проблемы, однако,

С справочной страницы:

Никогда не используйте get (). Потому что это так невозможно сказать, не зная данные заранее, сколько символов получает () будет читать, а потому получает () будет продолжать хранить символы прошлого конец буфера, это чрезвычайно опасно использовать. Он был использован для нарушить безопасность компьютера. Используйте fgets () вместо этого.

Таким образом, вместо gets, используйте fgets с потоком STDIN для чтения строк с клавиатуры

1 голос
/ 27 апреля 2010

Это должно работать нормально, поэтому что-то еще идет не так. Как предполагает Хоббс, у вас может быть новая строка на входе, и в этом случае это ничего не будет совпадать. Он также не будет использовать новую строку, поэтому если вы сделаете это в цикле, первый вызов перейдет на новую строку, а затем следующий вызов ничего не получит. Если вы хотите прочитать новую строку, вам нужен еще один вызов или используйте пробел в строке формата, чтобы пропустить пробел. Также неплохо проверить возвращаемое значение scanf, чтобы увидеть, действительно ли оно соответствует каким-либо спецификаторам формата.

Кроме того, вы, вероятно, хотите указать максимальную длину, чтобы избежать переполнения буфера. Итак, вы хотите что-то вроде:

char buffer[100];
if (scanf(" %99[^\n]", buffer) == 1) {
    /* read something into buffer */

Это позволит пропустить (игнорировать) любые пустые строки и пробелы в начале строки и прочитать до 99 символов ввода до и без новой строки. Конечные или встроенные пробелы не будут пропущены, только начальные пробелы.

0 голосов
/ 10 августа 2016
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *text(int n);

int main()
{
char str[10];
printf("enter username : ");
scanf(text(9),str);
printf("username = %s",str);

return 0;
}

char *text(int n)
{
fflush(stdin);fflush(stdout);
char str[50]="%",buf[50],st2[10]="[^\n]s";
char *s;itoa(n,buf,10);
// n == -1 no buffer protection
if(n != -1) strcat(str,buf);
strcat(str,st2);s=strdup(str);
fflush(stdin);fflush(stdout);
return s;
}
0 голосов
/ 27 апреля 2010

Бьюсь об заклад, ваш вызов scanf находится внутри цикла.Могу поспорить, это работает, когда вы в первый раз звоните.Могу поспорить, что он провалится только во второй и более поздние времена.

В первый раз он будет читать, пока не достигнет символа новой строки.Символ новой строки останется непрочитанным.(Скорее всего, внутренняя библиотека действительно читает ее и вызывает ungetc, чтобы ее не прочитать, но это не имеет значения, потому что с точки зрения вашей программы новая строка не читается.)

Во второй раз она прочитаетпока он не достигнет символа новой строки.Этот символ новой строки все еще ожидает в начале строки, и scanf прочитает все 0 символов, ожидающих его впереди.

В третий раз ... то же самое.

Вывероятно, это нужно:

if (scanf("%99[^\n]%*c", buffer) == 1) {

Редактировать: я случайно скопировал и вставил другой ответ вместо вопроса, прежде чем вставить% * c, как предполагалось.Эта результирующая строка кода будет вести себя странно, если строка ввода длиннее 100 байт, потому что% * c будет есть обычный байт вместо новой строки.

Однако обратите внимание, насколько опасно этосделайте это:

scanf("%[^n]%*c", string1);

потому что там, если у вас строка ввода длиннее буфера, ввод будет проходить по всем вашим другим переменным, стеку и всему прочему.Это называется переполнением буфера (даже если переполнение идет в стек).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...