2013-11-11 3 views
3

Я пытаюсь отформатировать пользовательский ввод с пространственным разделением для назначения программирования.Использование функции scanf во время цикла

По существу, входной состоит из произвольного числа выражений

L integer integer integer integer и C integer integer integer.

Например: L 1 1 5 7 C 4 5 3.

До сих пор мне удалось извлечь целые числа в зависимости от начального символа, и может перебирать строки с помощью функции Scanf:

char a; 
while(scanf("%c", &a) == 1){ 
    if(a == 'C'){ 
     int inputX, inputY, inputR; 
     scanf("%d %d %d", &inputX, &inputY, &inputR); 
     printf("%d %d %d\n", inputX, inputY, inputR); 
    } 
    else if(a == 'L'){ 
     int x1, y1, x2, y2; 
     scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 
     printf("%d %d %d %d\n", x1, y1, x2, y2); 
    } 
} 

К сожалению, хотя это и выводит желаемые целые числа, цикл (и приглашение пользователя) не завершается.

Может кто-нибудь, пожалуйста, просветит меня, почему это происходит?

+0

Вы пишете 'EOF' (по Ctrl + D в Linux или Ctrl + Z в Windows) в конце ввода? – timrau

+0

@timrau, загружающий 'EOF', заканчивает ввод, пока программа работает, но я ожидаю, что он закончится и в' Enter'. –

ответ

10

Это потому, что \n всегда здесь, чтобы сделать scanf("%c", &a) == 1 всегда правдой.
Измените ваш

while(scanf("%c", &a) == 1) 

в

while(scanf(" %c", &a) == 1) 
    //  ^space before format specifier. 

Пространство перед тем %c съест это \n оставленные scanf (по нажатию Enter ).

+0

Это, похоже, не работает; добавление пробела ничего не изменило. Есть идеи? –

+0

@haccks Я написал программу, которая читает некоторые символы. 'Е ("\ п 1. Дайте символ: \ п");' ' \t зсапЕ ("" % C», &ch); '' \t в то время (ч = '\ 0') { ' \t \t! '...' ' \t Е ("\ п 2. Дать символ: \ п");' ' Scanf ("% с", &ch);' ' }' Но работает эта программа, второй Printf печатается дважды. После добавления пробела перед '% c' он работал правильно! Не могли бы вы объяснить мне, почему мы должны добавить spece до'% c', чтобы второй printf был напечатан только один раз? –

+1

Причина прост, который я объяснил в приведенном выше ответе.Когда вы нажимаете клавишу «Enter», символ новой строки '\ n' переходит во входной буфер. Если 'a' является входным символом, то входной буфер будет содержать' a \ n'. Первый 'scanf' будет читать' a' оставить '\ n' в буфере для следующего вызова' scanf'. При вводе цикла ваш второй 'scanf' будет читать этот оставшийся' \ n' из входного буфера, и цикл запускается еще один раз, не дожидаясь ввода, и именно поэтому вы дважды получаете строку «Дайте символ». – haccks

2

Причина заключается в том, что scanf считывает непосредственно со стандартного ввода и блокирует и ждет ввода пользователя после обработки строки. Что вам нужно сделать, это прочитать строку и обработать эту строку в цикле while. Я изменил ваш код ниже.

char a; 
char line[1024]; 

fgets(line, 1023, stdin); // leave 1 character for null terminator 
while(sscanf(line, "%c", &a) == 1){ 
    if(a == 'C'){ 
     int inputX, inputY, inputR; 
     sscanf(line, "%d %d %d", &inputX, &inputY, &inputR); 
     printf("%d %d %d\n", inputX, inputY, inputR); 
    } 
    else if(a == 'L'){ 
     int x1, y1, x2, y2; 
     sscanf(line, "%d %d %d %d", &x1, &y1, &x2, &y2); 
     printf("%d %d %d %d\n", x1, y1, x2, y2); 
    } 
} 
0

Сочетание некоторых функций других сообщений и некоторых дополнений.
Использовать fgets() и %n внутри sscanf(). Обязательно проверьте результаты sscanf().

char line[1024]; 
while (fgets(line, sizeof line, stdin) != NULL)) { 
    char *s = line; 
    char Type; 
    int n; 
    while(sscanf(s, " %c%n", &Type, &n) == 1) { 
    s += n; 
    if(Type == 'C') { 
     int inputX, inputY, inputR; 
     if (3 != sscanf(s, "%d %d %d%n", &inputX, &inputY, &inputR, &n)) { 
     Handle_Syntax_Error(); 
     } 
     s += n; 
     printf("%d %d %d\n", inputX, inputY, inputR); 
    } 
    else if(Type == 'L') { 
     int x1, y1, x2, y2; 
     if (4 != sscanf(s, "%d %d %d %d%n", &x1, &y1, &x2, &y2, &n)) { 
     Handle_Syntax_Error(); 
     } 
     s += n; 
     printf("%d %d %d %d\n", x1, y1, x2, y2); 
    } 
    else { 
     Handle_Syntax_Error(); 
    } 
    } 
} 
Смежные вопросы