Reputation: 2067
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
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.
Upvotes: 1
Views: 337
Reputation: 2480
Your problem seems to be the value of n
; is that 0 when you type \n
?
I like the solution given here: to capture cin
with getline()
which returns a string. Then you can check with isempty()
if there was any input. You will need to convert to a number with stof()
or stol()
but that should be doable.
Upvotes: 0
Reputation: 1026
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.
Upvotes: 1
Reputation: 3489
You most likely just need to clear the stream at the end of the read_input
loop and make sure that you ignore whatever is left in the input buffer:
void read_input(int arr[], int &length) {
int n = 0;
std::cout << "Read input: " << std::endl;
while (std::cin >> n) {
arr[length++] = n;
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Although Ctrl-D
to mark the end of the sequence seems an unusual choice, why not just use a dedicated character to mark the end of input and safely discard it.
Upvotes: 0
Reputation: 190
The whitespace will not be discarded from the beginning of the input sequence. You can discard the whitespace with using the std::ws function which is a manipulator designed to extract and discard leading whitespace from the beginning of an input stream.
You can use from getline() for do it.
#include <iostream>
#include <string>
void read_input(int arr[], int& length) {
int n = 0;
std::cout << "Read input: " << std::endl;
std::string num_str{};
while (std::getline(std::cin >> std::ws, num_str)) {
try
{
n = std::stoi(num_str);
arr[length++] = n;
}
catch(...)
{
break;
}
}
}
int main() {
int array[100], length = 0;
int c = -1;
while (true) {
std::cout << "Menu: (TO DO)\n";
std::cout << "Your option: ";
std::string str;
std::getline(std::cin >> std::ws, str);
try
{
c = std::stoi(str);
}
catch(...)
{
c = -1;
}
if (c == 1) {
read_input(array, length);
}
if (c == 0) break;
}
}
Upvotes: 0
Reputation: 1
You should use for loop:
for(int i=0; i<5; i++)
{
std::cin>>n;
array[i]=n;
}
Or if you want to finish input on newline:
std::string input="";
while(input!="\n")
{
getline(std::cin,input);
n=std::stoi(input);
array[length++]=n;
}
Upvotes: 0