#c #scanf
#c #scanf
Вопрос:
Я прочитал это здесь, но я не могу это понять.
//assume a and b are char arrays
scanf("%[^,]s",a); // first scanf()
scanf("%[^,],s",b); // second scanf()
Я могу понять, что первый scanf()
будет сканировать строку до ','
обнаружения. Но как насчет второго?
В этой ссылке говорится, что первая scanf()
не уничтожит запятую, в то время как вторая ее уничтожит.
Что именно trash the comma
означает?
Комментарии:
1. удалить
s
из"%[^,]s"
и("%[^,],s"
2. Вы неправильно процитировали исходную ссылку. В строках формата нет
s
. «Мусор» означает «удалить из входного потока». Второй scanf удалит,
, что означает, что другойgetchar()
прочитает следующий символ после запятой.
Ответ №1:
scanf("%[^,]s",a);
прочитает до ,
и затем оставит ,
во входном буфере .
scanf("%[^,],s",a);
прочитает до ,
и после прочтения ,
отбросит это.
И оба они будут считывать и отбрасывать конечную строку s
.
Попробуйте этот пример кода и увидите разницу:
#include <stdio.h>
int main()
{
char a[10];
char b;
scanf("%[^,]s",a);
//scanf("%[^,],s",b);
scanf("%c", amp;b);
printf("%sn%c", a, b);
}
Комментарии:
1. спасибо, но сначала это также отбрасывается, я имею в виду, что если мы напечатаем это с помощью printf (), то результат будет таким же
2. @A.s.Bhullar Нет, первый не отбрасывает его. Разница в том, что осталось во входном потоке .
3. Ты имел в виду
scanf("%[^,],s",a)
во втором случае, верно?4. @Chnossos; Да. Это была опечатка. Я пропустил это
,
🙂5. Вы пробовали этот код:
#include <stdio.h> int main() { char a[10]; char b; scanf("%[^,]s",a); scanf("%c", amp;b); printf("%sn%c", a, b); }
?
Ответ №2:
Обратите внимание, что %[…]
это само по себе является полной спецификацией преобразования. Подробные сведения см. в спецификации POSIX для scanf()
или на справочной странице вашей системы.
Из ваших двух утверждений:
scanf("%[^,]s",a); // first scanf()
Такого рода работы, но на самом деле не делают того, что вы (вероятно) ожидаете от этого. Он считывает последовательность символов без запятой вплоть до первой запятой, а затем не соответствует s
, но не имеет способа сообщить об этом сбое. Следующим символом из входных данных будет запятая (или EOF, если во входных данных нет запятых).
scanf("%[^,],s",b); // second scanf()
Это тоже вроде как работает, но тоже делает не совсем то, что вы ожидаете. Он считывает последовательность символов без запятой, затем запятую, а затем s
, но у него также нет способа сообщить, прочитал ли он запятую или s
после нее. Если во входных данных есть запятая и s
после нее, то следующим входным символом будет тот, который следует за s
. Если есть запятая и не- s
, то следующим прочитанным символом будет не- s
. В противном случае следующее чтение вернет EOF.
Оба оператора написаны плохо. Было бы намного лучше, если бы код проверял статус возврата и был записан как:
if (scanf("%[^,],s", b) != 1)
…report problem…
Обратите внимание, что если следующим символом во входных данных является запятая, все операторы вернут 0, указывая, что никакая информация не была доступна для чтения b
.
Комментарии:
1. «Такого рода работы, но на самом деле не делают того, что вы ожидаете». Не имеете ли вы в виду «но не по той причине, о которой вы думаете».? В любом случае 1.
2. Есть ли существенная разница между двумя вариантами? Я немного изменил формулировку (с помощью «вероятно»), но я не вижу существенной разницы между «работает, но не делает того, что вы ожидаете» и «работает, но не по той причине, о которой вы думаете».
3. Да, есть существенная разница. Вы точно объяснили, почему это работает так, как ожидалось, даже если s не является частью спецификатора формата. Причина полностью отличается от ожидаемой.
Ответ №3:
Они оба помещают одни и те же символы в целевую переменную (a или b), но во втором ТАКЖЕ пропускается запятая, так что СЛЕДУЮЩЕЕ чтение не начнется с нее.