Использование ifstream в качестве fscanf - PullRequest
9 голосов
/ 17 января 2011

Предположим, что у меня есть следующие данные:

N (X_1,Y_1) (X_2,Y_2) .... (X_N, Y_N)

где N, X_i и Y_i - целые числа.

Пример:

2 (55,1) (521,7)

Чтобы прочитать это, я могу сделать что-то вроде этого (предположим, что все переменные определены и т. Д.):

fscanf(fin,"%d ",&N);
for (int i = 0; i < N; i++)
   fscanf(fin,"(%d,%d) ", &X[i], &Y[i]);

Вопрос в том, как мне это легко сделать, используя ifstream. Я могу получить строки, а затем я могу избавиться от нецифровых чисел и используя stringstream я могу получить два числа, но это кажется немного громоздким. Есть ли более простой и элегантный способ?

Спасибо

Ответы [ 2 ]

6 голосов
/ 17 января 2011
int n, x, y;
char c;
if (is >> n)
    for (int i = 0; i < n; ++i)
        if (is >> c && c == '(' &&
            is >> x &&
            is >> c && c == ',' &&
            is >> y &&
            is >> c && c == ')')
        {
            X[i] = x;
            Y[i] = y;
        }
        else
            throw std::runtime_error("invalid inputs");

Вы можете упростить все важные внутренние условия if, описанные выше, до ...

is >> chlit('(') >> x >> chlit(',') >> y >> chlit(')')

... с простым типом поддержки для потребления определенного символа:

struct chlit
{
    chlit(char c) : c_(c) { }
    char c_;
};

inline std::istream& operator>>(std::istream& is, chlit x)
{
    char c;
    if (is >> c && c != x.c_)
        is.setstate(std::iostream::failbit);
    return is;
}

Смотрите полную программу, иллюстрирующую это на ideone здесь .

В моем старом посте было что-то похожее для использования определенных строк.(Вышеприведенный chlit может быть шаблоном, но chlit<','>() некрасиво читать и писать - я бы предпочел доверить компилятору).

3 голосов
/ 17 января 2011
cin >> N;
for (int i = 0; i < N; i++)
{
    cin.ignore(100,'(');
    cin >> X[i];
    cin.ignore(100,',');
    cin >> Y[i];
    cin.ignore(100,')');
}

Он также может обрабатывать пробелы, так как он может читать вводные данные, такие как:

2  (  1  ,  3  )    (  5  ,  6  )

Демонстрация в ideone: http://www.ideone.com/hO0xG

...