C++ : istringstream conversion to long int doesn't work - c++

My problem is, I want to convert a string into a long int. For that, i use an istringstream that way:
long x;
string lString;
istringstream istr;
getLine(cin, lString);
istr.str(lString);
if(!(istr>>x)) return false; //Edited after answer below
(the conversion and the cin are actually in two different methods, I just put the related code together).
The following code returns false if I type "1", but not if I type "1.0". I could search for . in the string and add it if ther isn't, but isn't there a method to convert string to long ?

It's because of the operator precedence. The ! operator has higher precedence than the >> operator, so for the compiler what you have written is
if ((!istr) >> x)
You need to add your own parentheses:
if (!(istr >> x))

Related

How store integers given in a line in diferent variables? [duplicate]

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.

Return value of (std::cin >> variable)

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

while (cin>> struct str) in c++ how can I use?

I'm having a trouble when I use while(cin) with struct. Would someone please make me clear about this problem? I don't know whether this kind of post was asked or not. If it was please forgive me and my bad english as well.
struct ThiSinh{
string m_HT;
float m_H;
};
I overload operator >> for it
bool operator >> (istream& is, ThiSinh &ts){
getline(is, ts.m_HT);
is >> ts.m_H;
is.ignore();
return ???;
}
Because while (cin >> ThiSinh) require a bool type, so I dont know what number or data it should return. And how to break the while loop when I press ctrl + Z.
I have also tried
while(cin){
ThiSinh ts;
cin >> ts;
}
and it worked but I dont want to get that false data. So someone please helps me out. Thanks in advance.
Your operator >> returns a bool, which is extremely unusual for a stream extraction operator, and renders it unusuable in most streaming contexts. Such operators are expected to return a reference to the stream on which they operate:
istream& operator >> (istream& is, ThiSinh &ts){
getline(is, ts.m_HT);
is >> ts.m_H;
is.ignore();
return is;
}
This is how multiple exrtactions actually work:
std::cin >> a >> b >> c;
Effectively, this first does auto &tmp = operator>>(std::cin, a), and then calls operator>>(tmp, b), and so on.
The reason why streams (and by extension, stream extraction operations) can be used in conditionals is that std::istream (and std::ostream) defines a conversion to bool (which returns true iff the stream is in error-free state); that conversion is then invoked by the conditional.
In other words, this:
while (std::cin >> ts)
effectively becomes this:
while (static_cast<bool>(operator>>(std::cin, ts)))
and the cast is possible because operator>> returns std::istream& and std::istream defines a conversion to bool.

Mixed number class istream issues

I assigned myself some homework over the summer, and the project I am 98% finished with has come to a standstill due to this one problem.
I have a class called Mixed. It contains member data for a whole number, a numerator, and a denominator. I need to overload all of the common operators to allow multiplication, addition, comparison and streaming of objects of type Mixed. I have all the operators overloaded except for >> (the extraction operator).
All mixed numbers read in will be of format:
whole numerator/denominator
ex: 1 2/3, 0 7/8, -3 18/5, 0 -1/89
Header: friend istream& operator>> (istream &, Mixed);
CPP file: istream& operator>> (istream &in, Mixed m) {...}
For the assignment, I am limited to the iostream and iomanip libraries. My plan was to read in the values from the stream and assign them to temporary int variables (w, n, d) which I would then use with the Mixed constructor to create object m. Unfortunately, I cannot think of a way to separate the numerator and denominator. They are both ints, but they have a char (/) between them.
I cannot use getline() with its delimiter, because it assigns data to a char array, which I do not believe I can convert to an int without another library.
I cannot use a char array and then segment it for the same reason.
I cannot use a while loop with get() and peek() because, again, I do not think I will be able to convert a char array into an int.
I cannot use a string or c-string and then segment it because that requires external libraries.
Once again, I need to split a value like "22/34" into 22 and 34, using only iostream and iomanip. Is there some fairly obvious method I am overlooking? Is there a way to implicitly convert using pointers?
You could first extract the nominator, then the separating character, and then the denominator.
Example for illustration:
istream& operator>> (istream &in, Mixed &m) {
int num, denom;
char separ;
in >> num;
in.get(separ);
if (separ != '/')
in.setstate(ios::failbit);
in >> denom;
if (in) {
// All extraction worked
m.numerator = num;
m.denominator = denom;
}
return in;
}
Once again, I need to split a value like "22/34" into 22 and 34, using
only iostream and iomanip.
Couldn't you just read in the first integer, use get to get the next character, and then read the second integer? Something like this:
#include <iostream>
int main() {
using std::cin;
using std::cout;
int num;
int den;
while(cin) {
cin >> num;
if (cin.get() != '/') {
// handle error
}
cin >> den;
cout << num << "/" << den << std::endl;
}
return 0;
}
You can then make sure that the character read between the two integers was a '/' and handle appropriately if it isn't.

Multiple inputs on one line

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.