2015-10-12 3 views
3

Я искал и читал, что модификатор^утверждает, что игнорирует все, что вы помещаете внутри [] в scanf. Например:Что действительно делает модификатор^scanf?

int val; 
scanf("%[^abc] %d, &val); 
printf("val is %d", val); 

Теперь, если я вход abc42, я думал, что а будут проигнорирован и 42 будет откладываются в вал. Но этого не происходит.

Я также попытался подавить scanf, сделав его:

scanf("%*[^abc] %d, &val); 

, но это не сработало. Поэтому я смущен тем, что на самом деле.

+1

Ваш образец кода имеет несогласованные кавычки. Пожалуйста, напишите точно код, который вы пытаетесь –

ответ

5

Вы должны тщательно прочитать документацию scanf(3) и включить все предупреждения при компиляции (например, при использовании gcc -Wall -Wextra -gGCC ...); вы, вероятно, будете предупреждены с такой компиляцией. Вы должны также использовать результат scanf и запустить программу в отладчике (gdb)

scanf("%[^abc] %d", &val); 

читает два элемента, первый из которых строка символов вне множества {a, b, c} (и второй - целое число, идущее «нигде»).

Так ваша программа undefined behavior (UB), потому что вы называете scanf с одним аргументом меньше, чем следует, и потому, что первый аргумент должен быть место достаточно char широкого буфера. UB может быть действительно bad, поэтому вам нужно всегда избегать этого.

Вы можете попробовать:

int val= 0; 
char buf[32]; // 30+1 could be enough.... 
memset (buf, 0, sizeof(buf)); 
if (scanf("%30[^abc] %d", buf, &val) == 2) { 
    printf("got string %s and int %d\n", buf, val); 
} 
else { // handle scanf failure 
} 
+0

Незначительный: Непонятно, почему разница в 2 в 32, 30 с 'char buf [32]; ... scanf ("% 30 [^ abc]% d", ... '. Ожидаемое 1. – chux

6

Когда вы говорите, что вы хотите scanf игнорировать определенные символы, я думаю, что вы имеете в виду вы хотите scanf прочитать эти символы, а затем игнорировать их. Для того, чтобы сделать это, используйте формат %*[] спецификатор:

scanf("%*[abc] %d", &val); 

[abc] говорит scanf читать любое количество символов между скобками (т.е. а, б или в). * сообщает scanf, чтобы игнорировать эти символы, затем %d считывает значение в val.

^ спецификатор говорит scanf читать любое количество символов другой, чем между скобками, который является противоположностью того, что вы хотите сделать, я думаю.

+0

Если вы удаляете пробел в scanf, это терпит неудачу. Почему это? – user3246699

2

Он дает следующее предупреждающее сообщение, когда компилирую код.

test.c: 5: 2: предупреждение: формат '% [^ абв' ожидает аргумент типа 'символ *', но аргумент 2 имеет тип 'Int *' [-Wformat]
test.c: 5 : 2: warning: format '% d' ожидает соответствующий аргумент 'int *' [-Wformat]

Вы должны передать массив символов функции scanf, когда используете это.

Итак, измените строку scanf ниже, и проверьте, что происходит.

char buf[100]; 
int val; 
scanf("%[^[abc] %d",buf,&val); 

% [^ а] он читает строку, если символ в скобках другой, чем^это происходит, то он заполняет адрес массива символов с символами чтения. Итак, это используется, только когда мы читаем ввод строки.

+0

Действительно хотите 2' ['in' «% [^ [abc]% d» '? – chux

+0

вы можете использовать обратную косую черту перед скобкой, например scanf («% [^ \ [abc] », buf); –

+0

В вашем комментарии не встречается обратная косая черта' % [^ [abc] "' – chux

Смежные вопросы