Инъекция строки в 'cin' - PullRequest
       13

Инъекция строки в 'cin'

12 голосов
/ 26 сентября 2010

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

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

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

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

Ответы [ 3 ]

14 голосов
/ 26 сентября 2010

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

9 голосов
/ 26 сентября 2010

Если вы действительно хотите использовать 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, когда закончите из резервной копии.Я не гарантирую портативность этого; P

0 голосов
/ 26 сентября 2010

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

...