Использование scanf для чтения определенного количества символов в C?

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

В этом примере он терпит неудачу, когда я беру 4 символа, а его ввод в его файл - «ABCDy». «ABCD» — это то, что я должен читать, а «y» предполагается использовать позже, чтобы знать, что я должен перезапустить игру. Вместо этого, когда я использовал scanf для чтения «ABCD», он также читал «y». Есть ли способ обойти это с помощью scanf, предполагая, что я не буду знать, как долго должна быть строка до времени выполнения?


person Kira    schedule 09.12.2010    source источник


Ответы (4)


Обычно вы должны использовать что-то вроде "%4c" или "%4s" для чтения максимум 4 символов (разница в том, что "%4c" читает следующие 4 символа независимо от того, в то время как "%4s" пропускает начальные пробелы и останавливается на пробеле, если он есть).

Однако, чтобы указать длину во время выполнения, вам нужно немного посложнее, поскольку вы не можете использовать строковый литерал со встроенным в него числом «4». Один из вариантов — использовать sprintf для создания строки, которую вы передадите scanf:

char buffer[128];

sprintf(buffer, "%%%dc", max_length);
scanf(buffer, your_string);

Я, вероятно, должен добавить: с printf вы можете динамически указывать ширину или точность поля, помещая звездочку (*) в строку формата и передавая переменную в соответствующей позиции, чтобы указать ширину/точность:

int width = 10;
int precision = 7;
double value = 12.345678910;

printf("%*.*f", width, precision, value);

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

person Jerry Coffin    schedule 10.12.2010

Пытаться

scanf("%4s", str)
person ruslik    schedule 09.12.2010
comment
Он по-прежнему читается в y в конце. И я не знаю, как долго может быть значение. - person Kira; 10.12.2010

Вы также можете использовать fread, где вы можете установить ограничение на чтение:

char string[5]={0};
if( fread(string,(sizeof string)-1,1,stdin) )
  printf("\nfull readed: %s",string);
else
  puts("error");
person user411313    schedule 10.12.2010

Вы можете просто зациклить вызовы getc().

person nibot    schedule 10.12.2010
comment
Это аналогично тому, что кому-то, кто хочет нарисовать ровно 80 пикселей, нужно вызвать putpixel 80 раз. оба являются плохой идеей во всех контекстах, кроме академических и бенчмаркинговых, поскольку вместо одного запроса к серверу вы бомбардируете его произвольным количеством запросов, каждый из которых больше по размеру, чем результат. - person Dmitry; 10.11.2017