2013-08-28 3 views
2

Я пишу программу C для выбора данных со входа std, который начинается с числа, указывающего количество наборов данных, тогда есть N пар данных в форме : (xy), поэтому я пишу код, как показано ниже:читать данные и пропускать parenthese с помощью scanf

#include <stdio.h> 

int main() 
{ 
    int n_sets; 
    scanf("%d", &n_sets); 
    int i; 
    for(i = 0; i < n_sets; ++i) 
    { 
     int m, n; 
     scanf("(%d %d)", &m, &n); 
     printf("%d\t%d\n", m, n); 
    } 

    return 0; 
} 

но это не работает. После ввода номера набора данных программа напечатает неинициализированный m & n напрямую. Но когда я добавляю пробел перед (%d %d), он отлично работает. Кто-нибудь может это объяснить?

+0

1. Проверьте возвращаемое значение из 'scanf' 2. Используйте отладчик, чтобы узнать, что происходит не так. –

+0

Это напоминает мне' fflush() '.. – Lucio

+0

@Lucio: из того, что я помню, fflush на stdin является расширением Microsoft , – zentrunix

ответ

8

Когда у вас есть символьные литералы в аргументе scanf(), он ожидает найти эти литералы точно так же, как указано в строке формата.

scanf("%d", &n_sets); 

правильно читает n_sets, и останавливается на новой строки или другой символ пробела в буфере. Следующий scanf():

scanf("(%d %d)", &m, &n); 

рассчитывает найти открывающую скобку в начале ввода, но находит символ пробела вместо этого. Так оно терпит неудачу, и scanf() возвращается, не прочитав ничего. Следовательно, ваши m и n остаются неинициализированными, а результаты мусора.

Когда вы кладете в пространстве перед открывающей скобкой следующим образом:

scanf(" (%d %d)", &m, &n); 

он говорит scanf(), чтобы пропустить все ведущие пробелы перед скобками во входном буфере, так что программа работает правильно.

+0

спасибо, я понял! – jfly

2

изменение

scanf("%d", &n_sets); 

в

scanf("%d\n", &n_sets); 

и входные ваши n_sets окончания с [войти], она работает.

enter image description here

+0

См. Ответ выше из подробного. Он очень хорошо объясняет, что именно происходит. – Darwing

+0

@ Zenfeuer Я согласился и проголосовал за это – vvy

+0

FYI: Изменение «% d» на «% d \ n» или «% d» или «% d \ t» и т. Д. Будет иметь тот же эффект. В каждом случае символ пробела в формате будет соответствовать пробелу _any_. – chux

1

Это походит на вход в программу имеет некоторое количество пробелов перед значением, которое вы хотите зсапЕ разобрать. Пространство в строке говорит scanf игнорировать пробелы. Без него scanf ищет точное соответствие сразу.

2

Предположим, что ваш вход выглядит так:

2 (1 2) (3 4) 

Существует пространство (или новой строки?) После первого числа, так что изменить scanf в петле на:

scanf("\n(%d %d)", &m, &n); 
//  ^^ 
+0

ясно. Благодаря! – jfly