Search code examples
c++iostreamclion

std::cin >> c; gets ignored after reading numbers into array


I'm trying to input some numbers into an array. Pretty simple task.

int array[100], n = 0, length = 0;
std::cout << "Input numbers: " << std::endl;
while (std::cin >> n) {
    array[length++] = n;
}

I press shift + F10 in CLion, trying to run it and

Clion terminal

it won't end the while (I pressed enter 5 times in a row), it goes on forever. am I doing something wrong here?

I tried using std::cin.ignore() after each input. It does not seem to have any effect.

Thank you!

EDIT: It does successfully end when I press ctrl-D, but I've encountered another problem. (I edited the title)

I have this program:

void read_input(int arr[], int &length) {
    int n = 0;
    std::cout << "Read input: " << std::endl;
    while (std::cin >> n) {
        arr[length++] = n;
    }
}

int main() {
    int array[100], length = 0;
    int c = -1;

    while (true) {
        std::cout << "Menu: (TO DO)\n";
        std::cout << "Your option: ";
        std::cin >> c;

        if (c == 1) {
            read_input(array, length);
        }
        if (c == 0) break;
    }
}

What happens is, I enter the option:

1
Read input:
1
2
3
4
^D

Menu: (TO DO)
Your option:
Read input:
Menu: (TO DO)
Your option:
Read input:
Menu: (TO DO)
Your option:
Read input:
...

Basically, after it goes into read_input() and I give it some numbers, I press ctrl-D and it won't ask me again for an input/option, it will just read 1 for std::cin >> c; again and again and it will go on forever.


Solution

  • The approach of reading user inputs until Ctrl+D is not a good idea since it causes many problems to your program and may have potential errors when running on other platforms. Ctrl+D closes the system level pipe so I am not sure if there is a proper way to restore the input stream after being stopped by EOF. As I said, even if you find a solution that works in your environment but there is still a chance of getting a potential bug. Therefore, my suggestion is to use a sentinel (here, eof as string) to replace Ctrl+D.

    #include <iostream>
    #include <string>
    
    
    void read_input(int arr[], int &length) {
        std::cout << "Read input (enter `eof` when you are done): " << std::endl;
    
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
        std::string number; 
        while (std::getline(std::cin, number) && number != "eof")
        {
            arr[length++] = std::stoi(number);
        }
    }
    
    int main() {
        int array[100], length = 0;
        int c = -1;
    
        while (true) {
            std::cout << "Menu: (TO DO)\n";
            std::cout << "Your option: ";
            std::cin >> c;
    
            if (c == 1) {
                read_input(array, length);
            }
            if (c == 0) break;
        }
    }
    

    Output:

    Menu: (TO DO)
    Your option: 1
    Read input (enter `eof` when you are done): 
    1
    2
    3
    eof
    Menu: (TO DO)
    Your option: 1
    Read input (enter `eof` when you are done): 
    1
    2
    3
    4
    5
    eof
    Menu: (TO DO)
    Your option: 2
    Menu: (TO DO)
    Your option: 0
    Process exited with status 0
    

    You can replace eof by whatever you like except numbers for this task.