'==' operator not found - c++

So apparently this prgoram is not working. Software tells me that the '==' operator is missing. Could some tell me what to do about this and explain why his/her solution works?
#include <iostream>
using namespace std;
int main() {
int var{ 0 };
cout << "Bitte eine Ganzzahl eingeben: ";
if ((cin >> var) == false) {
cerr << "Falsche Eingabe - Keine Zahl\n";
exit(1);
}
system("pause");
//return 0;
}
And while we're at it. Why is it possible to execute 'cin' in the if statemant? I would have used 'cin' before the if statemant.

In modern C++, the status of a stream can be tested using an explicit operator bool. This means that it can be used directly as the condition in an if statement, but can't be implicitly converted to bool to compare with false. So you'd need the more idiomatic
if (cin >> var)
to test the status.
Why is it possible to execute 'cin' in the if statemant?
Because the condition can be any expression, as long as it has a result that can be converted to bool. The >> operator returns a reference to the stream, which can be converted via the operator I described above.

First cin is not something that you execute, like the print command of some other languages. It is an object of class istream that represents the standard input stream of chars.
The operator >> extracts formatted input from such streams. Its prototype is something like
istream& operator>> (int& val);
meaning it returns a reference to the istream itself, so you can chain operations like
cin >> foo >> bar;
so you can't compare the result of cin >> foo, which is a reference, to the constant false.
On the other hand, the operator "!" is overloaded and means the same thing as fail, so you can check that an operation succeeds like this
if ( ! (cin >> var) ) {
cerr << "something is going wrong" << endl;
}

std::istream has conversion operator to bool, but it has to be explicit (http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool):
explicit operator bool() const;
You can use an explicit conversion operator:
if ( (bool)(cin >> var) == false) {
cerr << "Falsche Eingabe - Keine Zahl\n";
}
or simply use:
if ( !(cin >> var) ) {
cerr << "Falsche Eingabe - Keine Zahl\n";
}

Related

C++: Splicing a String within cin Overload

I am trying to splice a cin>> string; which should be a complex number.
I am working within the class Complex, which deals with complex numbers.
I'm having a hard time splicing the string into separate components so I can arrange each substring and convert them into relevant doubles that correspond to imaginary or realpart.
When I run the code there is an error with how I am finding the string I think, it appears to be out of bounds.
This is the header and the definition of my function, overloading >>.
Header:
friend istream& operator >>(istream& inputStream, Complex& amt);
Definition:
istream& operator >>(istream& inputStream, Complex& amt){
cout<<"Please enter your complex number: ";
std::string str;
inputStream >> str;
//need different parts of string. imaginary, real, operand, 'i', and beginning sign.
std::size_t pos = str.rfind('-'|'+');
std::string str2 = str.substr(pos); // str2 = imaginarypart
if(str2.back()=='i'){
str2.erase( str2.end()-1 );
}
if(str2[0]=='+'){
str2.erase( str2.begin()-1 );
}
//str remains with realpart
return inputStream;
}
If you're merely looking for a way to input complex numbers, in any suitable format, I'm proposing a way simpler solution, using std::complex from the standard library: http://en.cppreference.com/w/cpp/numeric/complex/operator_ltltgtgt
Something like:
#include <complex>
#include <string>
#include <iostream>
bool
inputComplexNumber (std::istream& is, std::complex<double>& c)
{
std::cout << "Please enter your complex number: ";
is >> c;
return is.good();
}
int
main ()
{
std::complex<double> c;
if (inputComplexNumber(std::cin, c))
std::cout << c.real() << (c.imag() > 0 ? "+" : "") << c.imag() << "i" << std::endl;
else
std::cout << "Bad complex number." << std::endl;
}
Sample runs:
Please enter your complex number: (-69.1, 42.2)
-69.1+42.2i
Please enter your complex number: blah
Bad complex number.
If you really do want to stick to the pretty format on input, then I would recommend that you write a little grammar for this mini-language, and derive proper scanning and parsing functions from that. That's a bit of work, but it's well worth it in the end.

What is the return value of "stringstream>>something"?

What is the return value of the stringstream >> something? For example, the return value of stringstream_obj >> int_obj. I understand the return type is still the stream because of istream& operator>> (int& val). But what's the value? To be specific, here is my code.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main (void)
{
stringstream sss(string("0"));
int num;
if (sss >> num) // don't understand here
cout << "true" << endl;
else
cout << "false" << endl;
//output "true"
return 0;
}
As the comment, why is the output true? The sss contains only 1 character. Once "sss >> num", the returned "stringstream" should have empty content thus the value of the bracket should be false.
Appreciated,
operator>> returns a reference to the stream, as you said. Then, in the context of the if the stream is converted to a bool through the conversion operator which gives :
true if the stream has no errors, false otherwise.
You successfully read the '0' so the stream has no errors, try reading one again and you'll see the stream has errors and if(sss) evaluates to false.
In c++ in general when >> is used with streams it returns itself
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
In your case operator>> that does sss >> num returns sss
(I am assuming you are using c++11 which it looks like)
And then your sss aka stringstream has a bool operator
which returns true if the conversion was successful
so in summary the if statement is more like
if( convert sss to int and check if successful)
// success
else
// fail
This is good discussion you can read
http://www.cplusplus.com/forum/articles/6046/

fstream with a string delimiter or two char

I have this situation where I need to get two int values from each row inside a file with this format:
43=>113
344=>22
Is it possible to do someting like setting a delimiter equal to => and than use >> operator to assign ints?
ifstream iFile("input.in");
int a,b;
iFile >> a >> b;
Also can be done autoamtically to output with similar format?
oFile << a << b;
instead of
oFile << a << "=>" << b;
Thanks.
You can't do it directly, without any extra code when reading or
writing, but you can write a manipulator which handles it for
you more explicitly:
std::istream&
mysep( std::istream& source )
{
source >> std::ws; // Skip whitespace.
if ( source.get() != '=' || source.get() != '>' ) {
// We didn't find the separator, so it's an error
source.setstate( std::ios_base::failbit );
}
return source;
}
Then, if you write:
ifile >> a >> mysep >> b;
, you will get an error is the separator is absent.
On output, you can use a similar manipulator:
std::ostream&
mysep( std::ostream& dest )
{
dest << "=>";
return dest;
}
This has the advantage of keeping the information as to what the
separator is isolated in these two specific functions (which
would be defined next to one another, in the same source file),
rather than spread out where ever you are reading or writing.
Also, these data presumably represent some particular type of
information in your code. If so, you should probably define it
as a class, and then defined operators >> and << over that
class.
Given a and b are variables of inbuilt types, you can not define your own user-defined operators for streaming them (the Standard library already provides such functions).
You could just write out code with the behaviour you want...
int a, b;
char eq, gt;
// this is probably good enough, though it would accept e.g. "29 = > 37" too.
// disable whitespace skipping with <iomanip>'s std::noskipws if you care....
if (iFile >> a >> eq >> gt >> b && eq == '=' && gt == '>')
...
OR wrap a and b into a class or struct, and provider user-defined operators for that. There are plenty of SO questions with answers explaining how to write such streaming functions.
OR write a support function...
#include <iomanip>
std::istream& skip_eq_gt(std::istream& is)
{
char eq, gt;
// save current state of skipws...
bool skipping = is.flags() & std::ios_base::skipws;
// putting noskipws between eq and gt means whatever the skipws state
// has been will still be honoured while seeking the first character - 'eq'
is >> eq >> std::noskipws >> gt;
// restore the earlier skipws setting...
if (skipping)
is.flags(is.flags() | std::ios_base::skipws);
// earlier ">>" operations may have set fail and/or eof, but check extra reasons to do so
if (eq != '=' || gt != '>')
is.setstate(std::ios_base::failbit)
return is;
}
...then use it like this...
if (std::cin >> a >> skip_eq_gt >> b)
...use a and b...
This function "works" because streams are designed to accept "io manipulator" functions that reconfigure some aspect of the stream (for example, std::noskipws), but for a function to be called it just has to match the prototype for an (input) io manipulator: std::istream& (std::istream&).
If you have always have => as the deliminator, you can write a function that will parse lines of the document.
void Parse(ifstream& i)
{
string l;
while(getline(i,l))
{
//First part
string first = l.substr(0, l.find("=>"));
//Second part
string second = l.substr(l.find("=>")+2, l.length());
//Do whatever you want to do with them.
}
}

error: no match for 'operator>>' in 'std::cin >> stopat'

I'm trying to get back into C++, and this is my second program in a long while. Everything compiles just peachy, until it gets to cin >> stopat; where it returns what seems to be a fairly common error: error: no match for 'operator>>' in 'std::cin >> stopat'
I've looked through a few things explaining what causes this, but nothing I actually understand (due to my relative inexperience in programming). What causes this error, and how do I fix it in case I come across it again?
#include <iostream>
#include "BigInteger.hh"
using namespace std;
int main()
{
BigInteger A = 0;
BigInteger B = 1;
BigInteger C = 1;
BigInteger D = 1;
BigInteger stop = 1;
cout << "How Many steps? ";
BigInteger stopat = 0;
while (stop != stopat)
{
if (stopat == 0)
{
cin >> stopat;
cout << endl << "1" << endl;
}
D = C;
C = A + B;
cout << C << endl;
A = C;
B = D;
stop = stop + 1;
}
cin.get();
}
EDIT: Somehow, I didn't think to link the libraries referenced. Here they are: https://mattmccutchen.net/bigint/
You haven't shown us the code for BigInteger, but there would need to be a function defined (either in BigInteger.hh or in your own code) like this:
std::istream& operator >>(std::istream&, BigInteger&);
This function would need to be implemented to actually get a "word" from a stream and try to convert it to a BigInteger. If you're lucky, BigInteger will have a constructor that takes a string, in which case it would be like this:
std::istream& operator >>(std::istream& stream, BigInteger& value)
{
std::string word;
if (stream >> word)
value = BigInteger(word);
}
Edit: Now that you have pointed out the library that's being used, here's what you can do. The library itself should probably do this for you, since it provides the corresponding ostream operator, but if you look into that you will see that general-purpose, library-quality stream operators are more complex than what I'm writing here.
#include <BigIntegerUtils.hh>
std::istream& operator >>(std::istream& stream, BigInteger& value)
{
std::string word;
if (stream >> word)
value = stringToBigInteger(word);
}
What you've left out here is details about your BigInteger class. In order to read one from an input stream with the >> operator, you need to define operator>> (often called a stream extractor) for your class. That's what the compiler error you're getting means.
Essentially, what you need is a function that looks like this:
std::istream &operator>>(std::istream &is, BigInteger &bigint)
{
// parse your bigint representation there
return is;
}

overloading operator >>()

My knowledge of C++ is small as I have only taken a couple classes. I undersand the basic case of using a friend function to overload the input, output stream operator for the "simple book example" of a Point object that has x, y instance variables. I am looking at a real project now, trying to understand what someone wrote and am getting the error:
error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const char [2]' (or there is no acceptable conversion)
1> c:\program files\microsoft visual studio 9.0\vc\include\istream(1000): could be 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,signed char *)' [found using argument-dependent lookup]
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
Noob question (1), can someone explain what basic_istream is? The error points to:
template<class _Traits> inline
basic_istream<char, _Traits>& __CLRCALL_OR_CDECL operator>>(
basic_istream<char, _Traits>& _Istr, signed char *_Str)
{ // extract a signed char NTBS
return (_Istr >> (char *)_Str);
}
The other part the error points to is:
void input(std::istream &in = std::cin)
{in >> "(" >> X >> "," >> Y >> "," >> Z >> ")" ; }
inline friend std::istream& operator >> (std::istream& in, Coord &val)
{val.input(in); return in; };
Not sure what the error is looking at with my limited knowledge. It seems to be complaining about not the right type in the inline friend std::istream& operator>> function because of something wrong in the basic_istream template (which I'm not sure what is happening there). Any advice would be greatly appreciated. Thanks!
I'm pretty sure you can't parametrize istream extraction like that. It would be cool to be proven wrong though :)
Try this:
void input(std::istream &in = std::cin)
{
char t;
in >> t >> X >> t >> Y >> t >> Z >> t;
}
You can't use a string as an input in that way. You will need to use something like
char c;
cin.get() >> c;
if (c != '(') throw SomeError;
cin >> X;
cin.get() >> c;
if (c != ',') throw SomeError;
cin >> Y;
and so on.
First off, since you are new to C++: Do not trust the compiler error messages too much. In complicated code (templates, overloading...) you frequently get messages that are unrelated to the real issue.
Incorporating the comment on my answer: In your case though, the "," and similar objects are const, and the operator for the X, Y, Z is only declared on non-const objects, therefore not applicable. You'd either have to duplicate it, or only write a const version.
basic_istream is the real class behind istream -- the definitions look something like:
namespace std {
typedef basic_istream<char> istream;
typedef basic_ostream<char> istream;
typedef basic_istream<wchar_t> wistream;
typedef basic_ostream<wchar_t> wostream;
}
As to why you're getting the error message in the first place, the problem is pretty clearly with parts like:
some_istream >> "(";
You seem to want to read a character, and have it match that against an opening parenthesis, and (probably) fail if that's not what it finds. For better or worse, however, istreams don't really support that directly. To do it, you could do something like this:
char ch;
some_istream >> ch;
if (ch != '(')
// handle failure
Alternatively, you could just read a character, and assume it's what should be there without checking. This can also allow somewhat more flexible input formatting, so "1 2 3" would be accepted just as well as "(1, 2, 3)". For some cases (e.g., input entered directly by a person) that can be fairly helpful. In other cases (e.g., input from another program) any deviation in the input signals a problem.
The problem is this:
in >> "("
Conceptually, this makes no sense. You're trying to read input into a string literal. (That's like trying to read input into the constant 5.) The error is because a string literal is a const array of characters (hence the const char[2] type) and so cannot be read into.
You might want this:
void input(std::istream &in = std::cin)
{
char dummy = 0;
in >> dummy >> X >> dummy >> Y >> dummy >> Z >> dummy;
}
All this does is read those characters into a dummy variable. It works, but those characters could be anything.
Rather, you should probably do the following:
// if you do it more than once, make it a function
bool expect_char(std::istream& in, char expected)
{
char check = 0;
in >> check;
if (check != expected)
{
in.putback(); // replace it
in.clear(std::ios::failbit); // set fail bit
return false;
}
else
{
return true;
}
}
void input(std::istream &in = std::cin)
{
if (!in) // if stream is bad, just return
return;
if (!expect_char(in, '('))
return;
in >> X;
if (!expect_char(in, ','))
return;
in >> Y;
if (!expect_char(in, ','))
return;
in >> Z;
if (!expect_char(in, ')'))
return;
}
Now the only problem is that if extraction fails half-way, we have modified the point object. Ideally, it would be all or nothing. We store intermediate values, then copy them when it all works:
void input(std::istream &in = std::cin)
{
if (!in)
return;
if (!expect_char(in, '('))
return;
int newX; // or whatever type it is
in >> newX;
if (!expect_char(in, ','))
return;
int newY;
in >> newY;
if (!expect_char(in, ','))
return;
int newZ;
in >> newZ;
if (!expect_char(in, ')'))
return;
X = newX;
Y = newY;
Z = newZ;
}
And we get what we were after.