get_line.hpp

(plain text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef GET_LINE_HPP_20021029T1321
#define GET_LINE_HPP_20021029T1321

#include <iostream>
#include <string>
#include <climits>
#include <cctype>

template <typename T, typename E, typename Tr, typename A>
std::basic_istream<E, Tr> &
get_line (std::basic_istream<E, Tr> &is,
	  T &x,
	  const std::basic_string<E, Tr, A> &prompt,
	  std::basic_ostream<E, Tr> &os) {
  while (is) {
    os << prompt << std::flush;

    if (is >> x && (std::isspace(is.peek()) || !is)) {
      is.ignore(INT_MAX, '\n').clear(); // even on EOF, return must be .good()
      break;
    }

    else if (is.rdstate() == std::ios::failbit) {
      is.clear();
      is.ignore(INT_MAX, '\n');
    }

    else {
      break;
    }
  }

  return is;
}

template <typename T>
std::istream &
get_line (std::istream &is, T &x, const std::string &prompt = "> ") {
  return get_line(is, x, prompt, std::cout);
}

#endif