Ввод строки в 'cin'

У меня есть функция, которая читает пользовательский ввод из std:: cin, и я хочу написать unittest, который вставляет некоторые строки в std:: cin, так что последующее извлечение из std:: cin будет читать эту строку вместо паузы для ввода клавиатуры.

В идеале я бы изменил подпись функции, чтобы передать пользовательский istream в качестве параметров, но я не могу этого сделать, поскольку у меня есть фиксированный интерфейс, который я не могу изменить.

cin.putback() почти то, что я хотел, однако он вставляет только один символ за раз, и он вставляет их в обратном порядке (но я где-то читал, что вернул char, который изначально не был там может быть опасным, хотя на сайте не выясняется, почему). Я попробовал несколько методов для ввода строки в внутренний буфер cin.rdbuf(), но ни один из них не будет работать. Я также рассмотрел возможность использования внешнего тестирования script или создания подпроцесса, однако я бы хотел сначала рассмотреть тест в чистом С++.

Итак, есть ли способ поместить строки в cin? Или вы знаете, как лучше ввести "поддельный ввод с клавиатуры"?

Ответ 1

Если вы действительно хотите использовать std:: cin, попробуйте следующее:

int main() {
  using namespace std;
  streambuf *backup;
  istringstream oss("testdata");
  backup = cin.rdbuf();
  cin.rdbuf(oss.rdbuf());
  string str;
  cin >> str;
  cout << "read " << str;    
}

Вы можете восстановить std:: cin streambuf по завершении резервного копирования. Я не гарантирую его переносимость, P

Ответ 2

Вместо того, чтобы прикручиваться с помощью cin, вы можете заставить свою программу принять общий std::istream&. При нормальной работе просто передайте его cin. Во время unit test передайте ему поток ввода-вывода вашего собственного создания.

Ответ 3

cin.putback() гарантированно будет работать не более чем с одним символом, поэтому вы не можете putback целую строку. Используйте поток, который оборачивает cin и разрешает произвольную putback() последовательности putback(). Я думаю, что Boost.Iostream имеет что-то похожее, и если это не так, может быть полезно реализовать такую оболочку.