Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discarding letters except numbers with cin

Tags:

c++

input

I have this loop right now that reads in numbers and outputs them in decimal, octal, and hexadecimal:

while(1) {
    if (cin >> n)
    cout << internal << setfill(' ') << setw(10) << dec << n << internal << setw(12) << oct << n << internal << setw(9) << hex << uppercase << n << endl;
    if (cin.fail()) {
        break;
    }
}

However if I try to discard inputs that aren't numbers with this it won't read in the input after the letters:

if (cin.fail()) {
    cin.ignore();
}

How do I discard input but be able to read other input later on?

Sample Input:

23
678  786  abc
7777

Expected Output: dec, oct, hex


    23          27       17
   678        1246      2A6
   786        1422      312
  7777       17141     1E61
like image 773
khoanguyen_t Avatar asked Sep 19 '15 21:09

khoanguyen_t


People also ask

Does cin ignore whitespace?

Using cin. The cin object allows easy input of a single character. However, note that cin will not allow you to input a white space (blank, tab, newline) character.

What is the difference between Cin clear and CIN ignore?

cin. clear() helps in clearing the error flags which are set when std::cin fails to interpret the input. cin. ignore(), on the other hand helps in removing the input contents that could caused the read failure.

Does CIN discard newline?

cin leaves the newline character in the stream. Adding cin. ignore() to the next line clears/ignores the newline from the stream. This is used mainly with combinations of cin and getline.


1 Answers

You need to consume the offending content from cin and reset the error state. As long as failbit is set, all input operations will fail immediately.

while(1) {
if (cin >> n)
    cout << internal << setfill(' ') << setw(10) << dec << n << internal << setw(12) << oct << n << internal << setw(9) << hex << uppercase << n << endl;
else {
    if (cin.eof())
        break;
    cin.clear();               // Reset the error state
    std::string dummy;  
    if (!(cin >> dummy))       // Consume what ever non-integer you encountered
        break;
  } 
}

Alternatively, you can just always read a std::string and then try to parse that to a number with std::stoi:

for (std::string word; std::cin >> word;) {
    try {
        int n = std::stoi(word);
        // You output logic here
    }
    catch (std::exception&) {}
}

But this will probably overuse exceptions as you state that invalid input is not exceptional. On the upside, it means doing less logic "by hand".

like image 159
Baum mit Augen Avatar answered Sep 17 '22 15:09

Baum mit Augen