Trying to Read a Line of Keyboard Input in C++ - c++

I mam trying to complete a college assignment in C++ and am having trouble with what should be a very basic operation. I am trying to read a string of characters from the keyboard. This is the relevant code:
string t;
cout << endl << "Enter title to search for: ";
getline(cin, t, '\n');
I understand, that the last line is supposed to read the input buffer (cin , in this instance) and store the character in the 't' string until it reaches a new line character and then continue the program flow.
However, when I run my code in XCode, it just sort of jumps over the getline function and treats 't' as an empty string.
What's going on? I tried using cin >> t but that just read characters forever - Why cant I get this to behave?

The reason that the input operation apparently is skipped, is most probably (that means, ignoring possible peculiarities of a bugsy XCode IDE) that you have performed some input earlier and left a newline in the input buffer.
To fix that, make sure that you have emptied the input buffer after each input operation that logically should consume a line of input.
One easy way is to always use getline into a string, and then use e.g. an istringstream if you want to convert a number specification to number type.
Cheers & hth.,

From the docs page it looks like you want
cin.getline(t,256,'\n');
or something similar.

This sounds like an issue with the way Xcode is running your program. Try running your program directly from the terminal, and see if this is sufficient to fix your issue.

Related

in c++ program after pressing enter , "cin" will feed all Variables

I have a program that takes two numbers and shows them on the screen.
However, when I hit "enter" after I input the first number, my program shows the answers before letting me input the second number.
Why does this happen?
int main()
{
int n1;
float n2;
cin>>n1;
cin>>n2;
cout<<"int n:"<<n1<<endl<<"float n:"<<n2;
return 0;
}
I wanna input 0.25 and 35 but when I write 0.25 and hit enter suddenly shows the answer "int: n:0 float n:0.25" it doesn't let me write second num. my os is Win10 and this program compiled with DevCpp
It works when both variables are ints.
There is no difference between cin>>n1; cin>>n2; and cin >> n1 >>n2. Enter key only serves as signal to sychronize input buffer and stream buffer. cin doesn't input per line, it parses buffer when there is available volume of data. If parse incomplete, it waits. If parse can't be done, it stops and state bit changes. To continue parsing you have either ignore or clear part or whole buffer content.
Something wrong was entered in first line, causing cin to go into bad() state. Edge case might happen if you're running program through a remote terminal, some incorrect character could slip in, e.g. ^M generated by new line from Windows would break cin stream on Linux. That's also case if you input from a file which was saved on different platform. On Windows line ends consist of two characters, #10 and #13. On linux steams expect only #13 as a new line and buffer flush signal, #10 is an unexpected character.
Edit (after OP gave information about input data):
"0.25" would be parsed as "0" and ".25", that expected and documented stream behavior. Parsing for n1 had stopped as soon as stream encountered character which doesn't fit int pattern, which could be space, end of line, alphabetic or punctuation. Period considered a punctuation in this case
Then it tries to get a float from stream input and buffer contains ".25". It's a legal float notation and it gets assigned to n2.
When you have both "int", you cannot get second value at all with same input, it always will be 0, because cin locks up in bad state, i.e. method its istream::good() returns false. You have to check state of stream after reading variables. Any further formatted reading that wouldn't be able to parse .25 wouldn't advance stream past that point.
If you want to read from stream exclusively line by line, you have to use istream::getline() method to get the string. There is also method get which can acquire content of stream and ignore which allows to discard part of stream.

White space on the end of output string not printing with the string, but rather with the next printed line after it

I tried to print a line that asks for input from the user, get the input, then print again some line. The problem is that the white space at the end of the first printed line is printed not at the end of the line, but rather at the beginning of second printed line, after i get the input.
I'm completely new to C++ so I couldn't really try much, but i tried printing the code without the part that prompts the input from the user, and it prints the space just fine, but when i add std::cin << input; the space get's sent to the beginning of the second line.
My code:
int input;
std::cout << "Enter your favorite number between 1 and 100: ";
std::cin >> input;
std::cout << "Amazing... That's my favorite number too... wow..." << std::endl;
I want the output to be
Enter your favorite number between 1 and 100: //some input
Amazing... That's my favorite number too... wow...
(note the space before //some input)
Instead i get
Enter your favorite number between 1 and 100://some input
Amazing... That's my favorite number too... wow...
(note the space before Amazing)
Edit: I'm using Clion if it could be connected. Also, I tried to run the executable on powershell and it worked as expected, without the problem, so this has something to do with the Clion terminal. Also, i'm using windows 10 as my OS.
Second Edit: add my findings on my answer.
This seems to be a problem with buffered input of Clion. See this issue: https://youtrack.jetbrains.com/issue/CPP-7437
When you are using CLion, You can try disabling PTY (Help | Find Action > type "Registry" > open Registry > find and disable the run.processes.with.pty option)
CLion moving space into new line
Are you sure about that? I tried both in online shell and on local machine and it works as expected.
After checking I found out that this occurs only on the Clion Run terminal, so this has something to do with it exclusively. I'm currently trying to mess around with the settings. I will post a solution and an explanation here if I find it.
Edit: as mentioned in one comment, it could be the issue mentioned here https://youtrack.jetbrains.com/issue/CPP-7437.
In any case it is a Clion related problem exclusively, and not a C++ problem.
This problem is only applicable for the second line, if you leave that line empty then the problem will be fixed. Don't know about C++ but for C before the print statement you have to add: printf("\n");

C++ Primer 1.4.4 — Importance of EOF and how to write in a code that will end without EOF?

Referring to two questions:
Incorrect output from C++ Primer 1.4.4
Confused by control flow execution in C++ Primer example
My question is answered in both of those posts, but I want to delve further.
First, I know this is only the beginning, but let's say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a EOF? I can't expect someone running my program to know that they need to hit Control-Z.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
Also one guy in those questions somewhat answered the importance of EOF, but how come the program doesn't even post the final cnt - 1?
Let's say I do the numbers 10 10 10 20 20 20. Without EOF, this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
lets say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a eof? I can't expect someone running my program to know that they need to hit ctrl + z.
You could either tell the user explicitly to do a specific action to end input or the design of the window itself could tell the user the information implicitly. For instance, a dialog box could ask the user to enter input and click an OK button when done.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
It seems like you would rather use a newline character to terminate your input. An example of this usage could be std::getline. Instead of writing
while (std::cin >> val)
you could instead use
std::string line;
if (std::getline(std::cin,line))
and assume that your user's input only consists of one line of values. There are plenty of other ways to similarly achieve this task depending on how you want to constrain the user's input.
Let's say I do the numbers 10 10 10 20 20 20. WIthout eof this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
Without the eof your program is still executing the while (std::cin >> val) loop since std::cin >> val has not yet received invalid input.
Since the line
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
occurs after that while loop finishes execution, you don't (yet) see any information about the three 20's in the input.
When you are reading a sequence of inputs you'll need some indication when your down. That could be a sentinel value ("enter 999 to stop reading"; you'd need to detect that while reading), an invalid input ("enter X to stop reading"; when reading an int the value X is illegal and causes the stream to got into failure mode, i.e., have std::ios_base::failbit set), or the more conventional "there isn't anything more to read". For a file, the last conditions is straight forward. When reading data from the console you'll either need to teach people how to terminate the input or you'll need to use a different approach.
If you want to intercept any keypressed and react on them directly you may do so, too. You could, e.g., use ncurses and control your input via that. You could also set the concole to non-buffering (on POSIX systems using tcgetattr() and tcsetattr() to clear the ICANON flag) and deal directly with all key presses to decide whether you want to continue reading or not.
Although I'm certainly up to doing fancy I/O stuff I normally don't bother: users will understand the "end of input" character and just deal with it. That is, my input normally looks something like this:
while (in >> whatever_needs_to_be_read) { ... }
... or, if the input is genuinely line oriented
for (std::string line; std::getline(in, line); ) { ... }
The function doing this input will then be called with a suitable std::istream which may be std::cin although I have typically some way to also read from a file (in addition to the shell-privided input redirection).
BTW, despite some indications in the questions referenced, "EOF" is not a character being read. It is a character entered, though (normally). ... and it is quite conventional to "know" the end of input character (on POSIX systems a ctrl-D and on Windows a ctrl-Z). You can use other indicators, e.g., the "interrupt" (ctrl-C) but that takes more work and doesn't integrate nicely with stream. To use the interrupt chacter you'd need to setup a signal handler for SIGINT and deal with that. One slightly annoying part of doing so is that if you get it wrong you'll need to find a different way to kill the program (e.g. on POSIX using ctrl-Z to put the process to sleep and kill it via a harsher signal).

Getline() Not keeping Application Open?

I'm a first semester C++ student and in class we are building a BMI calculator (Win32 Console Application). I've gotten everything to work just fine, except for one of the instructions, which is wait for user to press enter to close application.
I had success using the system("PAUSE"); statement but in the past I would declare a string variable, like for example, initialize string genVar; and then use getline(cin, genVar); and when the user pressed Enter, the application would close, but it didnt work this time. The application would simply close. It worked just fine with pause, but not with getline().
Is using getline() for this purpose bad practice? Anyone have any clue why it didn't work?
Thank you in advance!
I know this is an old post, but look at the solution which I posted in this question:
C++ Multiple Program Issues (rand, conversion, crashing)
It explains (as chris mentioned in a comment) that getline tends to leave in a new line character in the buffer, which needs to be cleared and reset. Answer above explains it.
std::cin and std::getline do not mix well in general, you usually want to stick to one or the other in a program to avoid input errors and bugs. Your getline probably is grabbing a left over input from as earlier std::cin. I would recommend using this:
std::cout << "Press ENTER to continue...";
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
return 0;
}
you'll need to include <limits> for this to work correctly.
you can also use the getch() function in the place of std::getline() IMHO

Why do I have to press enter Twice?

For some reason in my program when I reach a certain spot, I have to press Enter twice in order to get it to submit. I added the clear to keep it from skipping input and the ignore() to keep it from keeping any extra characters in the buffer. I enter my input and then it drops down to a new line, I hit Enter again and it enter the input and continues the program no problem but I'm wondering why. Here's a code snippet:
cin.ignore();
cout << "Enter Student Major (ex. COSC): ";
cin.getline(student.major, 6);
for(int i = 0; i < sizeof(student.major); i++)
student.major[i] = toupper(student.major[i]);
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Any suggestions?
It seems to me that you are tossing too many cin.ignore() around, not knowing exactly why they are needed and when to put them there.
There are two common circumstances where cin.ignore() is needed to "make input work right":
when mixing formatted and unformatted input;
to recover from a formatted input error.
In both cases, you want to get rid of spurious characters from the input buffer; if there isn't any such character (which is probably what happens in your program), cin.ignore() will pause the execution and wait for user input - after all, you asked it to ignore some characters, and dammit, it will obey to its orders.
(although ignore() by default would "eat" just one character, whatever it may be, the execution is paused until a newline is found because by default cin is line buffered - new input is not examined until a newline is recieved)
Case 1:
cin.ignore() calls are often needed if you are performing an unformatted input operation (like getline) after performing a formatted input operation (i.e. using the >> operator).
This happens because the >> operator leaves the newline in the input buffer; that's not a problem if you are performing only formatted input operations (by default they skip all the whitespace before trying to interpret the input), but it's a problem if afterwards you do unformatted input: getline by default reads until it finds a newline, so the "spurious newline" left will make it stop reading immediately.
So, here you will usually call cin.ignore(...) call to get rid of the newline just after the last formatted input operation you do in a row, guaranteeing that the input buffer is empty. Afterwards, you can call getline directly without fear, knowing that you left the buffer empty.
It's a bad idea, instead, to put it before any getline, as you seem to do in your code, since there may be code paths that lead to that getline that have the input buffer clean, so the ignore call will block.
Case 2:
when istream encounters an error in a formatted input operations, it leaves the "bad" characters in the buffer, so if you retry the operation you get stuck endlessly, since the offenders are still there. The usual clear()/ignore() idiom comes to the rescue, removing the whole offending line from the input buffer.
Again, you don't put the clear()/ignore() sequence at random, but only after you get an input error from a formatted input operation (which sets the failbit of the stream).
Now, aside from these cases, it's uncommon to use cin.ignore() (unless you actually want to skip characters); don't spread it around randomly "just to be safe", because otherwise you will encounter the problem you described.
The answer can be found here.
The extraction ends when n characters have been extracted and discarded or when the character delim is found, whichever comes first. In the latter case, the delim character itself is also extracted.
So in your case, the program will not continue until a '\n' character is received.
I think cin.ignore(numeric_limits<streamsize>::max(), '\n'); is expecting a \n in the input and it doesn't find it, so you have to press Enter again for it to find it.