New to C++ and am currently reading "Accelerated C++" (Koenig & Moo) but struggling to understand the logic of left-associativity in one particular section. Specifically, on p.62, the expression:
is >> s.name >> s.midterm >> s.final;
Evaluates
( is >> s.name >> s.midterm ) >> s.final;
That is, the first term inside () reads-into the second s.final. However, is characters stream into each s.name, s.midterm and s.final variables independently - how can this be? Am I confusing operations (relational against arithmetic) or how do I interpret this directional flow of information in a strict technical sense?
If you are new to the language I think a good interpretation for is >> x is as follows:
is is an object capable of using low level functions to request an input from the keyboard (or another device, including a file)
the << operator is the one to which you can feed is and x so that is does it's job and puts in x what it reads from the device
the value returned by the expression is >> x is essentially of the same nature as is, and can be used again in the same way.
As regards the 3rd point, refer to this page on operator<</operator>> for std::basic_string: you'll see that the signature is the following (cleaning it up from things not relevant to the question)
template <class CharT>
std::basic_istream<CharT>&
operator>>(std::basic_istream<CharT>& is,
std::basic_string<CharT>& str);
where it's clear that operator>> returns an object of the same type as its first input, i.e. the expression is >> x, after having the side effect of reading stuff from device and altering the value of x, eventually evaluates to an object of the same type as is.
If you really want to go deep into this, you can write this simple code:
#include <iostream>
#include <string>
int main()
{
int x;
std::string y;
std::cin >> x >> y;
}
and, with the help of your IDE, jump to the two >>s to explore what they do or look like. Among other things, you'll find out that
the first >> will result in a call to basic_istream<_CharT, _Traits>::operator>>(int& __n), which is a member function of the class basic_istream<_CharT, _Traits> and returns and object of that class by reference, basic_istream<_CharT, _Traits>&. What is the object on which ???.operator>> is called? Well, it's obviously std::cin. And what is the object that the call returns? Go to the bottom of that function and you'll find return *this;, so it returns std::cin itself, possibly modified in the body of the function;
the second >> results in a call to std::operator>>(basic_istream<char>& __is, basic_string<char>& __str);, which is a free function in the std namespace. This, unlike the previous one, explicitly takes a first argument of type basic_istream<char> (which in our example is the expression (std::cin >> x), but like the previous one returns a reference to the stream, basic_istream<char>&, which is still an altered version of std::cin, ready to be used again.
To address this comment of yours:
reads-into string s.name a stream of characters input by the user, which are then in-turn used to identify the string to be read-into s.midterm
When you see (is >> x) >> y, the fact that "is reads stuff from input and puts it in x" is a side effect (yeah, the side effect is the main reason why we are doing this, but it's still a side effect); the non side effect is that is >> x takes is and x into input and gives you back an object of the same type of is.
In (is >> x) >> y, the x does influence what can be read in y, but only in the sense that is >> x doesn't give you back exactly is but an altered version of it.
The first alteration is that whatever you have read into x, if x was, say, a int, char *, or whatever, can't be read again, so it's not available for y.
Another alteration, is that x might be some type of object that is merely used to alter std::cin. I don't have an example for this right now, but I have one for std::cout: in std::cout << std::boolalpha << true; the effect of the first << is to take std::cout and give you back something which will print true/false instead of 1/0 when you feed it with a bool.
Related
I have looked to no avail, and I'm afraid that it might be such a simple question that nobody dares ask it.
Can one input multiple things from standard input in one line? I mean this:
float a, b;
char c;
// It is safe to assume a, b, c will be in float, float, char form?
cin >> a >> b >> c;
Yes, you can input multiple items from cin, using exactly the syntax you describe. The result is essentially identical to:
cin >> a;
cin >> b;
cin >> c;
This is due to a technique called "operator chaining".
Each call to operator>>(istream&, T) (where T is some arbitrary type) returns a reference to its first argument. So cin >> a returns cin, which can be used as (cin>>a)>>b and so forth.
Note that each call to operator>>(istream&, T) first consumes all whitespace characters, then as many characters as is required to satisfy the input operation, up to (but not including) the first next whitespace character, invalid character, or EOF.
Yes, you can.
From cplusplus.com:
Because these functions are operator overloading functions, the usual way in which they are called is:
strm >> variable;
Where strm is the identifier of a istream object and variable is an object of any type supported as right parameter. It is also possible to call a succession of extraction operations as:
strm >> variable1 >> variable2 >> variable3; //...
which is the same as performing successive extractions from the same object strm.
Just replace strm with cin.
I am a C++ beginner,
#include <iostream>
int main()
{
char v1;
// valid no warning
std::cout << (std::cin >> v1) << std::endl; // return value of the expression expected
return 0;
}
// output: 1
// return value of the expression is 1?
Is the return value of (std::cin >> v1) really 1? Why?
I don't know of a current compiler that will accept your code as it stands right now. g++, clang and Microsoft all reject it, saying they can't find an overload to match the arguments (i.e., an operator<< for ostream that takes an istream as an operand).
It's possible to get the result you've posited with code on this order: std::cout << !!(std::cin >> v1) << "\n";. Depending on the age of the compiler and standard with which it complies, this does one of two things.
With a reasonably current compiler, this will use the Boolean conversion on the istream to get it to match the ! operator, then apply that (twice) to the result, so you write out the result of that operator.
With old enough compilers, there won't be a Boolean conversion operator, but there will be an overload of operator!, which also does a conversion to Boolean (but negated in sense, of course). The result of that will then be negated by the second !.
Either way, you end up writing out a Boolean value (or int containing zero or one on an old enough compiler) that indicates whether the stream is in a failed or successful state.
This is done to allow you to check input as you're reading it, so you can process input data sanely. For example, when/if you want to read all the values in a file, stopping at the end of the file, or when you encounter something that can't be interpreted as the desired type, you can write code on this general order:
// read integers from a file and print out their sum
int temp;
int total = 0;
while (std::cin >> temp) {
total += temp;
}
std::cout << total << "\n";
The while loop uses the conversion to Boolean to determine whether an attempt at reading a value was successful or not, so it continues reading values as long as that happens successfully, and quits immediately when reading is unsuccessful.
One common source of errors is to write a loop on this order instead:
while (std::cin.good()) { // or almost equivalently, check for end of file.
std::cin >> temp;
total += temp;
}
But loops like this get the sequence incorrect. One common symptom of the problem with this is that the last number in the file will be added to the total twice instead of once.
std::cin >> v1 returns cin; Not sure what type it gets converted to for std::cout, but most likely it indicates the state of cin, where 1 is good
Is the return value of (std::cin >> v1) really 1
No, see the ref for cin, it will return a istream.
Your codes will not work, we can not pass ::istream (std::cin) to operator<< of a std::ostream (std::cout).
Shoule be like the following:
char v1;
cout << "Input a char:";
cin >> v1;
The program only works for Pre-C++11 because the conversion to bool is not explicit.
Starting from C++11, the program will no longer work because the conversion to bool is explicit.
Note that std::cin >> v1; returns std::cin and not 1. But there is no operator<< for std::ostream that takes a std::cin.
The reason it works for Pre-C++11 is because in this case the conversion to bool was not explicit. But starting from C++11, the conversion to bool was made explicit and so the code no longer compiles.
For example,
bool b = std::cin; //WORKS for Pre-C++11 but FAILS for C++11 & onwards
bool b{std::cin}; //OK, WORKS for all versions(Pre-C++11 as well as C++11 & onwards) because in direct initialization we can use explicit conversion
Here is the code:
// pointers to structures
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct movies_t {
string title;
int year;
};
int main ()
{
string mystr;
movies_t amovie;
movies_t * pmovie;
pmovie = &amovie;
cout << "Enter title: ";
getline (cin, pmovie->title);
cout << "Enter year: ";
getline (cin, mystr);
(stringstream) mystr >> pmovie->year;
cout << "\nYou have entered:\n";
cout << pmovie->title;
cout << " (" << pmovie->year << ")\n";
return 0;
}
Taken from http://www.cplusplus.com/doc/tutorial/structures/. I was hoping I could get clarification on a few things.
What is getline and how does it work? I tried looking up the documentation, but I'm still having trouble understanding. Also, what exactly is cin and how is it being used with getline?
If I understand correctly, pmovie->title essentially says that pmovie points to the member title of the object amovie? If so, and it's not already clear from the explanation to #1, how does getline (cin, pmovie->title) work?
Now this (stringstream) mystr >> pmovie->year is giving me the most trouble. What is a stringstream, and are we using it like we would cast a double as a int, for example?
Thank you all!
What is getline and how does it work? I tried looking up the documentation, but I'm still having trouble understanding. Also, what exactly is cin and how is it being used with getline?
The getline function reads a line from a istream. The cin stream refers to your standard input stream, the one you would normally get input from. It is being passed to getline to tell it which input stream to get a line from.
If I understand correctly, pmovie->title essentially says that pmovie points to the member title of the object amovie? If so, and it's not already clear from the explanation to #1, how does getline (cin, pmovie->title) work?
The getline functions reads a line from cin and stores it in pmovie->title which is passed by reference.
Now this (stringstream) mystr >> pmovie->year is giving me the most trouble. What is a stringstream, and are we using it like we would cast a double as a int, for example?
A stringstream is a class that makes a string act like a stream. This is kind of confusing syntax (C-style cast) that makes it a bit harder to understand what it is happening. Basically, a temporary stringstream is created and initialized with the contents of mystr. A stringstream, when initialized with a string, gives you a stream from which you can read those contents. The >> operator reads from an output stream, in this case, into pmovie->year, which is again passed by reference.
By the way, it seems to me like you're trying to understand unusually complex and confusing uses without yet understanding the more basic uses of these objects. That's a very hard way to learn.
Most of the questions don't seem to be about structures at all. So, I'm addressing the issue which is related to the title rather than those about streams:
If I understand correctly, pmovie->title essentially says that pmovie points to the member title of the object amovie? If so, and it's not already clear from the explanation to #1, how does getline (cin, pmovie->title) work?
You misunderstand. I would guess, that this is the root of your confusion: pmovie points to a movies_t object. As it happens, in the sample code it is initialized to point to the movies_t object named amovie.
Now, each movies_t object has two members, i.e., subobjects: a title and a year. To access the title component of a movies_t pointed to by a pointer you use pmovie->title. To access the year component instead you'd use pmovie->year.
The one thing I say about streams, though, is this: You should always check that your input was successful before assuming the read was successful. For example, you would check that reading a line was successful using
if (std::getline(std::cin, pmovie->title)) {
// deal with a successfully read title
}
cin is a special stream defined by C++ to work with standard output (usually the keyboard, but can be almost anything). getline is a function that allows you to read text from a stream into a buffer until the platform's line ending is encountered (Line Feed on UNIX, Carriage Return Line Feed of Windows and DOS).
pmovie->title says that pmove is a pointer to a structure that has a member called title. This refers to that member. Because getline takes a string& (String reference), it happily accepts the string referenced by pmovie->title.
stringstream defines an implicit constructor that converts strings to stringstreams. the >> operator gets input from a string and converts it to the target type (the type of the operand to the right of the >>) and puts it there. This is just a way of converting a string to an integer.
I have looked to no avail, and I'm afraid that it might be such a simple question that nobody dares ask it.
Can one input multiple things from standard input in one line? I mean this:
float a, b;
char c;
// It is safe to assume a, b, c will be in float, float, char form?
cin >> a >> b >> c;
Yes, you can input multiple items from cin, using exactly the syntax you describe. The result is essentially identical to:
cin >> a;
cin >> b;
cin >> c;
This is due to a technique called "operator chaining".
Each call to operator>>(istream&, T) (where T is some arbitrary type) returns a reference to its first argument. So cin >> a returns cin, which can be used as (cin>>a)>>b and so forth.
Note that each call to operator>>(istream&, T) first consumes all whitespace characters, then as many characters as is required to satisfy the input operation, up to (but not including) the first next whitespace character, invalid character, or EOF.
Yes, you can.
From cplusplus.com:
Because these functions are operator overloading functions, the usual way in which they are called is:
strm >> variable;
Where strm is the identifier of a istream object and variable is an object of any type supported as right parameter. It is also possible to call a succession of extraction operations as:
strm >> variable1 >> variable2 >> variable3; //...
which is the same as performing successive extractions from the same object strm.
Just replace strm with cin.
I'm attempting to construct a function that will perform a sanity check on the user's response to a number of questions, each of which would ideally be a non-zero integer. How can I construct a function that would be able to accept a parameter of any data type, but only have a single parameter? For example:
bool SanityCheck(<type id> number)
where <type id> would cover any data type.
It's not clear exactly what you really want here. Unverified input from a user normally comes in the form of a string. Typically you read in a string, verify that it has the desired form (e.g., for an integer, all digits). If it has the right form, you convert that to the desired type, and use it. If it doesn't, you ask the user to re-enter their data, usually with a prompt like "Please enter an integer between 1 and 10".
A function template is sort of a direct answer to the question you asked, but I have a hard time imagining it being of any help in a situation like you've described. A function template is most often of use in cases where you have to carry out some operations that are syntactically the same across a number of types. For example, it lets you add two numbers, regardless of whether those happen to be of type short, int, long, float, double, long double, etc. That only works because they're really all numbers, and you can reasonably use + to add any of them together.
When you're dealing with some unknown input, that doesn't apply though -- you need to verify enough about the data to be sure the operation is sensible and meaningful before you can do much else with it; it's pretty hard to get a meaningful result from comparing (for example) 7 to a sunset.
C++ is a statically typed language. What type a variable is of will be fixed at compile-time and cannot be changed at run-time. What users enter, however, will only be known at run-time, and cannot be known at compile-time. Therefore your question makes no sense.
When you expect an integer from a user, then the best way would be to try to read an integer, and check whether this succeeds:
int i;
std::cin >> i;
if(!std::cin)
throw "Stupid user blew it!"; // or some real error handling
However, the catch with this is that, once an input operation fails, an input stream enters a bad state and the data that couldn't be read stays in the input buffer. If you want to handle this gracefully, would have to clear the stream's error state flags, and make it ignore whatever is in the input buffer.
So sometimes it might be easier to first read a string
std::string input;
std::cin >> input; // either read up to any whitespace, or
std::getline(std::cin, input); // newline, or
std::getline(std::cin, input, '\t'); // tab, or whatever you want
because this always succeeds, and then try to convert it into whatever data you need. The way to do this is via string streams:
std::istringstream iss(input);
int i;
iss >> i;
Now you can check the string stream's state
if(!iss)
and if the conversion failed, std::cin will still be usable and the erroneous input read from its buffer.
However, there's one more catch: If a user inputs '"42 thousand"', then this won't catch the error. The remaining characters will be in the string streams input buffer and silently ignored. So what you usually need to do for such a conversion is to test whether the string stream's buffer is fully read, that is: reading reached EOF. You can check for this by invoking iss.eof(). However, if you read a whole line, there might be extra whitespace at the end, which you wouldn't want to make the conversion fail, so you need to read extra whitespace before you check for EOF: iss >> std::ws. (std::ws is a stream manipulator that "eats" consecutive whitespaces.)
by now, the conversion would look like this:
std::istringstream iss(input);
int i;
iss >> i >> std::ws; // you can chain input
if(!iss.eof())
throw invalid_input(input);
Of course, this is pretty elaborated for a one-time conversion and I wouldn't exactly swear by the life of my kids that there isn't a nice improvement left that I hadn't thought of yet. So you would at least want to wrap this into a function and put that into your toolbox for reusing it (and improving on it, if you find an error):
bool convert_to_int(const std::string& str, int& result)
{
std::istringstream iss(input);
iss >> result >> std::ws;
return iss.eof();
}
Or, generic for any type:
template< typename T >
bool convert_from_string(const std::string& str, T& result
{
std::istringstream iss(input);
iss >> result >> std::ws;
return iss.eof();
}
Even better would be to use a ready-made off-the-shelf solution for this. Boost has just such a thing with its lexical_cast.
Here's a skeleton algorithm for the whole input routine:
int i;
do {
read string input
convert to int i
while(!conversion succeeded);
With the bits from further above, you should be able to fill in the missing parts.
Use templates:
template <typename T>
bool SanityCheck(T number);
The sanity check may vary for different types. As this is a homework, I won't post any more code just hint you with a Google search term "partial template specialization".
Ok, I think I get what you actually want now.
I imagine your situation is something like this:
Read some user input (maybe using std::cin).
Check to make sure it is an int.
Use the int if it is one.
If this is the case then you do not want a function that can handle different data types, because the user cannot enter different data types, he can only enter characters and you have to choose what datatype you want to store that as.
I think this is what you need:
bool valid = false;
int input = 0;
while (!valid)
{
std::string inputStr;
std::cin >> inputStr;
valid = isInteger(inputStr);
if (!valid)
std::cout << "Please enter an integer." << std::endl;
else
input = atoi(inputStr.c_str());
}
std::cout << "You entered " << input << "!" << std::endl;
You're going to have to write isInteger yourself, but hopefully you get the idea.
Option 1: use boost::variant if you want it to be a single function
Option 2: overload this function for all types that you need
Making your function a template function would achieve this.
template<typename T>
bool SanityCheck(T number);
A lot of online surveys that I'm asked to fill out don't ask me to enter data but only select an option from 1 to 5. 1 = Totally Agree, 5 = Totally Disagree. This seems a more efficient way of collecting user input since you have total control over data type and all I have to do is highlight an option box.