Предположим, что у меня есть вход следующим образом:
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. Я могу получить строку, а затем я могу избавиться от nondigits и использовать stringstream. Я могу получить два числа, но это кажется немного громоздким. Есть ли более простой и элегантный способ?
Спасибо
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; }
См. Полную программу, иллюстрирующую это на идеоне здесь .
Старый пост моей сделал что-то подобное для потребления определенных строк. (Вышеупомянутый chlit
может быть шаблоном, но chlit<','>()
уродливо читать и писать – я бы скорее доверял компилятору).
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 )
Демонстрация на идеоне: http://www.ideone.com/hO0xG