0

I am just reviewing C++ and I don't know why 3 and 5 are the only working option. I already converted it to if-else statement but still the same issue. Below is the code:

#include <iostream>
using namespace std;

int main()
{
    char c, s[50] = {'\0'};
    int num;

    cout << "Select cin method:" << endl;
    cout << "1. cin.get(c);" << endl;
    cout << "2. cin.get(s, 10);" << endl;
    cout << "3. cin.get(s, 10, '*');" << endl;
    cout << "4. cin.getline(s, 10);" << endl;
    cout << "5. cin.read(s, 10);" << endl;
    cout << "Select: " << flush;
    cin >> num;

    switch (num) {
        case 1:
            cin.get(c); //  cin >> c;
            break;
        case 2:
            cin.get(s, 10); //  cin >> s; max length 10, '\n' as string terminator
            break;
        case 3:
            cin.get(s, 10, '*');    //  cin >> s; max length 10, '*' as string terminator
            break;
        case 4:
            cin.getline(s, 10);     //  cin >> s; max length 10, '\n' as string terminator
            break;
        case 5:
            cin.read(s, 10);        //  cin >> s; max length 10, records '\n'
            break;
        default:
            break;
    }

    if (num == 1)
        cout.put(c);                //  cout << s;
    if (num >= 2 && num <= 5)
        cout.write(s, 15);          //  cout << s; max length 15
}

Whenever I input 1/2/4 for num, it just bypasses the switch and else-if statements. I already tried checking what num is getting by "cout << num" and the value it gets is correct. I don't receive any error message either. Below is the sample of what I am getting:

Select cin method: 
1. cin.get(c); 
2. cin.get(s, 10); 
3. cin.get(s, 10, '*'); 
4. cin.getline(s, 10); 
5. cin.read(s, 10); 
Select: 1 
-------------------------------- 
Process exited after 1.676 seconds with return value 0 Press any key to continue
Bill
  • 13,485
  • 4
  • 38
  • 54
ab cd
  • 3
  • 3
  • 6
    Please describe how #1, 2, and 4 are not working. What behavior or error message did you get? What were you expecting to see? – Bill Mar 25 '15 at 14:04
  • It's just a review about cin methods. Whenever I input 1/2/4 for num, it just bypasses the switch and else-if statements. I already tried checking what num is getting by "cout << num" and the value it gets is correct. I don't receive any error message either. Below is the sample of what I am getting: Select cin method: 1. cin.get(c); 2. cin.get(s, 10); 3. cin.get(s, 10, '*'); 4. cin.getline(s, 10); 5. cin.read(s, 10); Select: 1 -------------------------------- Process exited after 1.676 seconds with return value 0 Press any key to continue . . . – ab cd Mar 25 '15 at 14:08
  • You can't see white characters in print. Try surrounding the `c` and `s` value with some braces or quotation marks when printing them out... – CiaPan Mar 25 '15 at 14:11
  • 1
    Note that after the first input (`num`), you probably press the "enter" key which appends a `\n` to the input stream which is what will be read by `cin.get` and `cin.getline` (the default delimiter version). – a_pradhan Mar 25 '15 at 14:12
  • @CiaPan: Whenever I select 1/2/4, it doesn't even asks me for num. It bypasses "cin >> num" and the switch/if-else statements. – ab cd Mar 25 '15 at 14:15
  • By stepping through in a debugger or adding debug output statements, you would easily see the switch is not bypassed and that `s` gets a new value, just like 3 and 5. – chris Mar 25 '15 at 14:20
  • It obviously does not "bypass the switch and else-if statements". Concentrate on figuring out what `cin` is doing. You could have entirely abstracted away the switch and figured out a small reproducing example of asking the user for a number then doing `cin.get(c)`. Then you'll find that there are a ton of duplicates of the question, with your answer! – Lightness Races in Orbit Mar 25 '15 at 14:23
  • This might be the most comprehensive such answer I've come across: http://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction – chris Mar 25 '15 at 14:26
  • @chris: Oh thanks. I still don't know how to run the debugger. But all of you are right, it does not bypass the statements. I tried putting an output in one of the condition and it shows. – ab cd Mar 25 '15 at 14:27
  • Whenever you select 1/2/4, it doesn't even asks you for num... because your selection (1 or 2 or 4) was input into `num`! And then the code is executed which either inputs a single character (case 1) or a string (case 2) or a line (case 3). Case 1 inputs a newline char which terminates your `num` input, other two cases read an empty string terminated by that newline. I told you to surround `cout` output with some additional characters, then you would have noticed they get split into two lines by a newline character printed from `c`. – CiaPan Mar 26 '15 at 11:18

1 Answers1

3

It doesn't bypass the switch, it executes it correctly. The problems is that, after reading the number, the input stream has an extra character in it (the \n you press after the number) and that causes the behavior you're seeing for cases 1, 2 and 4. The next read operation you're doing in those cases finds that \n and stop reading.

To fix it you can add something like this after the cin >> num:

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

(and include <limits>

Ionut
  • 5,048
  • 1
  • 14
  • 17
  • Wow, thank you very much! This worked. I haven't seen this code before. I am now wondering how cin really works. – ab cd Mar 25 '15 at 14:34
  • Well, it works as one might expect from a stream: you advance in the stream by reading stuff from it. The idea is that you should know what the stream contains. In your case, if you type "1" on your keyboard, the stream will contain `1\n`. `cin >> num` reads only the `1`, so the next read from the stream will start with the `\n`. What that line of code does is to basically clear the rest of the stream, so the next read operation starts clean. – Ionut Mar 25 '15 at 14:50
  • Oh I get it. I also tried to change 'cin.get(c)' to 'cin >> c' and it worked. Now I already know additional information about the difference of 'cin' from 'cin.get()' and about istream. Thanks. – ab cd Mar 25 '15 at 14:58