There are two issues with your use of std::istream::peek()
:
- This function access the next character and does not skip leading whitespace. You probably want to skip leading whitespace before determining what the next character is, e.g., using the manipulator
std::ws
:(std::cin >> std::ws).peek()
. - The result from
std::istream::peek()
is not achar
. Instead, it is anstd::char_traits<char>::int_type
(which is a fancy spelling ofint
). The result may, e.g., bestd::char_traits<char>::eof()
and if the value of'0'
happens to be negative (I'm not aware of any platform where it is; however, e.g., the funny character from my name'ü'
is a negative value on platforms wherechar
is signed) you wouldn't get the correct result, either. That is, you normally compare the result ofstd::istream::peek()
against the result ofstd::char_traits<char>::to_int_type()
, i.e., you'd use something like this:std::cin.peek() == std::char_traits<char>::to_int_type('0')
That said, your program doesn't check whether it could successfully read the nominator and the denominator, separated by a slash. You always want to verify that reading was successful, e.g., using something like
if ((std::cin >> nominator >> slash >> denominator) && slash == '/') {
...
}
Just for entertainment, you can create a manipulator for testing that a character is a slash, indeed:
std::istream& slash(std::istream& in) {
if ((in >> std::ws).peek() != std::char_traits<char>::to_int_type('/')) {
in.setstate(std::ios_base::failbit);
}
return in;
}
This way, you'd encapsulate the test for slash. If you need to use this in multiple places this is quite handy.