Output when a user enters string for an int variable - c++

I'm currently reading Stroustrup's book on C++. In the user input section, it has the following example -
#include <iostream>
#include <string>
using namespace std;
int main(){
cout << "Please enter your first name and age:\n";
string firstName = "???"; // "??? means don't know the name"
int age = -1; // -1 means don't know the age
cin >> firstName >> age;
cout << "Hello " << firstName << " (age " << age << ")\n";
}
As per the book, we initialize the age variable so as to get a predictable value if the input fails.
The example says that the input 22 Carlos will produce an output of Hello 22 (age -1).
I've typed in the same code in a text editor (Sublime Text), but when I run the code with the above input, I get an age of 0 (not -1).
Here's the screenshot of the outputs I get -
output image from terminal.
And, here's the version of the compiler that I'm using -
compiler-version.
Can anyone explain as to why I don't get -1 as the age output, as the book claims?

The short answer is that both are correct if that version of the book is more than a few years old.
Prior to C++11, the default behaviour of operator>> extracting an integer was to leave it unchanged if the extraction fails.
In C++11, this behaviour was changed to store 0 into the integer when extraction fails.
I don't have knowledge of why the change was made, but my guess is that it prevents a common class of undefined behaviour from people leaving a variable uninitialized and then not checking that extraction succeeded before using the variable.
Unfortunately, the machinery behind formatted input is quite lengthy, but the condensed version is that the call ultimately boils down to num_get::get(), where this behaviour is specified.1
1: For your interest, it's also possible to attach a different facet for formatted input to use instead, meaning you could specify whatever behaviour you want for failure.

Related

Why does cin evaluate before getline even though cin comes after getline? [duplicate]

This question already has answers here:
getline() does not work if used after some inputs [duplicate]
(3 answers)
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 4 years ago.
Question
I am making some code notes for my friend in C++, and in one section, I have shown my friend three different ways of getting an input.
In my code, I have getline written on line 14, and cin written on line 18. So logically speaking, getline should be evaluated first, but it doesn't. Is this because getline is slower than cin? Could you also tell me how I can fix it?
I am fine if you mix up the format of the code, or add new code in whatever way you want, but don't delete any of the code already written to help me solve my problem.
Code
The first way is getting a number, the second way is getting a string, and the third way is getting multiple values.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int userInputedAge;
cout << "Please enter your age: ";
cin >> userInputedAge;
string userInputedName;
cout << "Please enter your name: ";
getline(cin, userInputedName);
int userInputedHeight, userInputedFriendsHeight;
cout << "Please enter your height, and a friend's height: ";
cin >> userInputedHeight >> userInputedFriendsHeight;
}
Here is the output.
Please enter your age: 13
Please enter your name: Please enter your height, and a friends height: 160
168
As you can see, I didn't have a chance to input my answer to Please enter your name: Why?
This has nothing to do with evaluation order, and lines of code don't randomly switch places at runtime.
When you were prompted for an age, you entered a number, and then you hit enter. Granted, you did so for a good reason — it was the only way to signal to your terminal that it should send over what you've typed so far.
But that enter consists of an actual character (probably a newline, possibly a carriage return as well) which is still in the buffer. This causes the next input operation, a getline, to complete immediately. It has read an empty line.
Make your code skip that newline.

Proper use of EOF (can it be used multiple times in a program?)

In my intro to programming course (c++), the instructor told us to:
"Write a program that inputs an unspecified number of integer ("int")
values and then outputs the minimum value and the maximum value that
were entered. At least one value will always be input. (read all input
until EOF). For extra credit make your program also work when the user
doesn't enter any ints at all (just the EOF.)"
I wanted to get fancy, so, in my solution, when just EOF is entered, the program responds with "Oops! You didn't enter anything. Please try again, this time entering at least one integer: " and prompts for input again.
My instructor is saying that this answer is wrong because
After the EOF, there should be no more input to a program (neither
expected by the user nor the program) — using the EOF to switch from
“one mode” of input to another mode of input isn’t supporting the
standards.
Every definition of EOF I've found on the internet doesn't seem to support my professor's definition. EOF, from what I can tell, is simply defined as the end of the current file. It seems perfectly valid to accept input from a user until EOF, do something with that input, and then ask for additional input until EOF again.
Because this is an online course, I was able to review everything we learned relating to EOF and we were only told that EOF meant "End of File" and could be 'used to signal an end to user input' (important, because, even if my professor was wrong, one could argue that I should have adopted his standards if he had specifically told us to. But he didn't tell us to).
What is the proper way to use EOF with user input? Is my professor's statement that "After the EOF, there should be no more input to a program" the standard
and expected way to use EOF? If a program accepts a variable amount of input, does something with it, and then accepts more variable input, is it not acceptable to use EOF with those inputs (aka don't use while(cin >> user_input) in that scenerio)? If so, is there a standard for what should be used to signal end of input in a scenario where you're accepting variable input multiple times?
My exact solution to the assignment is below. My solution to the main assignment "Write a program that inputs an unspecified number of integer ("int") values and then outputs the minimum value and the maximum value that were entered" was considered correct, by the second part of the assignment "make your program also work when the user doesn't enter any ints at all (just the EOF.)" was deemed incorrect ("make the program also work" is the only prompt we were given).
Thanks so much for any feedback!! Obviously, I'm skeptical of my professors feedback / decision, but, in general, I'm just trying to get a sense of C++ community standards.
#include <iostream>
#include <iomanip>
#include <string>
#include <stdlib.h>
using namespace std;
int main(){
string user_input;
int int_input, min_user_input, max_user_input;
bool do_it = true;
cout << "Hi John," << endl;
cout << "Please enter a few integers (signal EOF when finished): ";
while(do_it) {
cin.clear();
cin >> user_input;
if (user_input.empty()) {
cout << endl;
cout << "Oops! You didn't enter anything. Please try again, this time entering at least one integer: ";
}
else {
try {
int_input = atoi( user_input.c_str() );
min_user_input = int_input;
max_user_input = int_input;
while(cin >> int_input) {
if (min_user_input > int_input) {
min_user_input = int_input;
}
if (max_user_input < int_input) {
max_user_input = int_input;
}
}
cout << endl;
cout << "The max user input was: " << max_user_input << endl;
cout << "The min user input was: " << min_user_input << endl;
do_it = false;
}
catch (std::invalid_argument) {
cout << endl;
cout << "Oops! You didn't enter an integer. Please try again, this time only entering integers: ";
do_it = true;
}
}
}
return 0;
}
Note: additional feedback I got on this submission was: to not use c libraries (apparently stdlib.h is one) and that, on some computers (though, apparently, not mine), #include <stdexcept> will be needed to compile.
Answer
Short answer: my instructor is correct. When used with cin, no additional user input should follow an EOF signal. Apparently, in some cases the program won't let you enter more information, but, as #hvd points out
Although your system may let you continue reading from the same file
in the specific case that it is coming from a TTY, due to EOF being
faked there, you shouldn't generally rely on that.
Aka, because I'm using a terminal to enter user input, the program happens to work. In general, it won't work though.
As #RSahu answers, EOF just shouldn't be used to signal the end of variable length cin multiple times in a program. Importantly
There is no standard means, or commonly practiced coding standard, of
indicating when user input has ended for the time being. You'll have
to come up with your own mechanism. For example, if the user enters
"end", you can use it to deduce that the user has ended input for the
time being. However, you have to indicate to the user that that's what
they need to enter. Of course, you have to write code to deal with
such input.
Because this assignment required the use of EOF, what I was attempting to accomplish was, unintentionally, prohibited (aka receive input, check it, possibly receive more input).
Proper use of EOF (can it be used multiple times in a program?)
There is no single EOF. There is EOF associated with every input stream.
If you are reading from a file, you can reset the state of the std::ifstream when it reaches EOF to allow you to read the contents of the file again.
However, if you are reading data from std::cin, once EOF is reached, you can't read from std::cin any more.
In the context of your program, your professor is right. They are most likely talking about reading from std::cin.
EOF, from what I can tell, is simply defined as the end of the current file.
It is. Note that in particular, what it doesn't mean is the automatic start of a new file.
Although your system may let you continue reading from the same file in the specific case that it is coming from a TTY, due to EOF being faked there, you shouldn't generally rely on that. Try program </dev/null and see happens when you try to automate your program.

C++ skipping the new line key?

I am trying to get the user to input some data and then storing it in a structure, however I am having troubles knowing which function I should use and what's the difference? cin or getline()? Either function I use, it seems like it takes in the '\n' key and makes my program crash, but I am not 100% if that's the problem... Since it keeps crashing.
I've played around with both of them and here is what I have.
string temp;
int id;
cout << endl << "Full name (last, first): ";
cin >> temp;
cin.ignore(1, '\n');
myData[fileSize] = parseName(temp);
cout << endl << "ID: ";
cin >> id;
myData[fileSize].id = id;
cout << endl << "Address: ";
cin >> temp;
temp.copy(myData[fileSize].address, temp.length(), 0);
The variable fileSize is just which element the array is currently at and the function parseName splits the name into last and first.
I been reading on a couple of functions like, cin.ignore() and noskipws, but not sure how to use them. By the way, the way the user should input the data is "last, first", with a comma and white space after (this is what the parsing function is looking for).
Also I am not sure if the address section is the best way to do this, I have the structure myData.address to be a character array, because I don't know how to work with strings. I am still not confident with C++. Thanks for any help.
EDIT: If I comment out the ID and Address parts, the program loops itself 6 times saying I have an invalid entry (which is part of main), so it reads 6 or 7 keys after I press enter.
If I leave everything the way it is, this is what I get.
Full name (last, first): terminate called after throwing an instance of 'std::ou
t_of_range'
what(): basic_string::copy
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Process returned 3 (0x3) execution time : 4.328 s
Press any key to continue.
You should use cin.getline() instead for this case, and the cin.ignore is not necessary.
Here is an examination of the two methods - std::cin.getline( ) vs. std::cin
Also, check your parseName function and try testing it in isolation without any user I/O.

Check if "cin" is a string

I have a simple little script I am coding, and I am trying to not allow people to enter a string, or if they do make it revert to the beginning of the function again. Here's the input code I have:
int main()
{
cout << "Input your first number" << endl;
cin >> a;
cout << "Input your second number" << endl;
cin >> b;
}
The rest of the code beyond this part works just fine for what's going on, although if a string is entered here it obviously doesn't work.
Any help would be appreciated.
You may find this post useful,
How to check if input is numeric in C++
Basically you can check the input, whether it is numeric value or not. After checking whether the given input is numbers, then you can add a while loop in main to ask user to repeat if input is not a valid number.
Every input is a string. If you want to know if a entered string can convert to a number, you have to read in a string and try to convert it yourself (eg with strol).
An alternative would be to check if the reading from cin failed, but personally i don't like it because cin.fail() covers more error situations than just a failed type conversion.
There's a library function may help,you can check it after input:
int isdigit(char c);
Tips:
1.You should include such files :
# include <ctype.h>
2.If c in 0 ~ 9 ,return 1 ; else return 0.

How to read aloud c++ expressions with the input/output operators?

I feel pretty stupid, but I'm just starting to learn c++ after coming from other languagues, and I cannot for the life of me comprehend statements that use "<<" and ">>". I know it is simple, but it confuses me every time.
The book I'm using made a really good recommendation to read const declarations from right to left. Is there any similar method for "<<" and ">>"?
i like to say "gets".
cout << "some expression = " << expr << endl;
i'd say that as "cout gets some expression, gets expr, gets endull." similarly if you're reading from a stream, it's your variable that "gets" a value from the input...
On the phone, back when I was a consultant frequently needing to "read aloud" C++ code to clients' employees on the phone, I (explaining once or twice, then they got it) read "input" operator >> as "absorb" and "output" operator << as "emit". "get" and "put" would work just as well if they didn't conflict with alas-too-common other uses. But that doesn't seem to have much to do with right-to-left vs left-to-right, just with your Q's title about "reading aloud" -- "cin absorb x" or "essteedee cout emit blach emit essteedee endl" kinds of "reading code aloud" (e.g. on the phone)!-)
I typically read them from left to right, like so:
cout << setw(6) << val << endl;
"Send to cout, with a width of 6, the contents of val, and then end the line and flush."
or
cin >> val;
"Get from cin the contents of val."
It does take a little bit of special consideration in that you can't just say specific words for each token.
To understand C++, you have to understand that C++ has many of the most powerful tools to build abstractions. cout is nothing but a stream. So, it is very acceptable to mimic the concept of stream.
For example,
std::cout << "hey"; // '<<' is something like the direction of the `data`
throws things in the stream with the same syntax and conventions, infact there is only one syntax for all types.
Also,
std::cin >> number;
extracts the next value of the type specified by number and put it in number.
It just make sense when you think about streams in C++. You can see this in most modern C++ libraries, for example with Boost you can do this:
boost::filesystem::path mypath;
....
mypath = mypath/filename;
The division operator is replaced with '/' or '\' depending on the system you are targeting :)
I never thought too much about it but I suppose you could say "Streams to" or "Streams from" eg.
cout << mysting << endl;
"cout streams from mystring streams from endline"
cin >> myvalue;
"cin streams to myvalue"
I just made that up but it makes sense to me.
This is easy enough the object that the symbol is pointing to on the receiving end. So:
cout << "Enter First Name: ";
cin >> FirstName;
in this code, cout in usually stdout and is "receiving" the characters "Enter First Name", FirstName which is presumably a variable is "receiving" the data from cin which is probably stdin.
A simple way to distinguish the two is like so.
cout << "Some fancy string...";
In this example your are taking a string and sending it to the world (monitor).
cin >> x;
In that one you take an value from the world (keyboard) and save the it into x.
Hence the direction Value >> X.