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;
}
Related
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.
this is my function
void global::readData(lifeform &p)
{
std::ifstream ifs("data.txt");
int i=0,i_str=0;
std::string str,str2;
std::getline(ifs,str);
std::stringstream ss(str);
if(i<31) {
std::getline(ss,str2,',');
std::istringstream toint(str2);
toint >> i_str;
if(i_str ==1) { //here i_str can get 1
p.newgame=1;
while(i<31) {
std::getline(ss,str2,',');
toint >> i_str;
if(i==0) {
p.setName(str2); //this also works
}
if(i==1) {
p.setMaxHp(i_str); //doesnt work
}
if(i==2) {
p.setQName("main",str2); //works
}
i++;
//....
}
}
this is data.txt
1,furkan,100,No mission,
i tried to get what is written on the data.txt to str.there is no problem so far.after than i wanted to convert string to int it worked in the first converting but not the rest
i changed 1 to 0 to see if it works or not and it works but the rest i_str doesnt work
1) std::istringstream get his own copy of str2. It don't watch changes of this variable.
2) And how you should do it:
char c;
ss>>i_str//read int value from stream
>>c;//and throw away separator
You don't need getline here.
Warning: this answer is kind of overkill for the specific job at hand. It uses a couple of fairly general-purpose utilities that make the job easy, but probably would be worth writing if this was the only time/place you had a use for them (but it's not--they turn out to be quite useful in general, once you have them). I keep them in an "input_utils.h", where I can use them from almost anything quite easily.
The first is an input operator for a constant string. That may sound utterly pointless (if it's constant, you obviously can't read into it). What it does is read some fixed input from a stream, and verify that what was in the stream matches what you expected. The code looks like this:
std::istream &operator>>(std::istream &is, char const *label) {
if (is.flags() & std::ios::skipws)
while (std::isspace((unsigned char)is.peek()))
is.ignore(1);
while (is.peek() == *label) {
is.ignore(1);
++label;
}
if (*label)
is.setstate(std::ios::failbit);
return is;
}
This lets us read (most of) the commas in your input quite easily--verify that they're present, but otherwise ignore them. So, to read three numbers separated by commas, we would do something like this:
input_stream >> number1 >> "," >> number2 >> "," >> number3;
At least to me, the meaning seems pretty simple, straightforward and obvious (and the applicability to the job at hand seems almost equally obvious).
The second has a clear and obvious intent, but the implementation is a little less trivial than I'd like (but I don't know a way to make it any simpler and still do the job). Its code looks like this:
class line_proxy {
std::string &s;
char delim;
public:
line_proxy(std::string &s, char delim) : s(s), delim(delim) {}
friend std::istream &operator>>(std::istream &is, line_proxy const &p) {
std::getline(is, p.s, p.delim);
return is;
}
};
line_proxy line(std::string &in, char delim = '\n') {
return line_proxy(in, delim);
}
We use it like this:
std::string s;
input_stream >> line(s); // equivalent to `std::getline(input_stream, s);`
Again, even though the implementation is a bit on the complex side, the use seems pretty obvious (at least to me).
Once we have these, your job borders on trivial. The one part that I'd do that might initially seem a little on the tricky side would be implementing the reading in a stream extraction operator for the lifeform class:
#include "input_utils.h"
struct lifeform {
int index;
std::string name;
int level;
std::string mission;
friend std::istream &operator>>(std::istream &is, lifeform &f) {
return is >> f.index
>> ","
>> line(f.name, ',')
>> f.level
>> ","
>> line(f.mission, ',');
}
We might want to be able to write out a lifeform as well:
friend std::ostream &operator<<(std::ostream &os, lifeform const&f) {
return os << "Index: " << f.index
<< ", name: " << f.name
<< ", level: " << f.level
<< ", mission: " << f.mission;
}
...and a little code to test them and see that they work correctly:
int main() {
std::istringstream input("1,furkan,100,No mission,");
lifeform f;
input >> f;
std::cout << f;
}
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";
}
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.
I have asked this question previously here and a similar question was closed.
SO based on a comment from another user, I have reframed my question:
In the first post, I was trying to read tha data from a file into an array with a struct.By using indata << p[i] and is >> p.fId, I was able to read values from data file into PersonId.
Now I want to try this:
struct PersonId
{
int fId;
};
struct PersonData
{
public:
typedef PersonData* Ptr;
PersonData();
PersonId fId;
istream& read(std::istream&);
};
istream& PersonData::read(std::istream& is)
{
is >> fId;
return is;
}
istream& operator >> (istream& is, PersonData &p)
{
// is >> p.fId;
return p.read(is);
}
int main ()
{
ifstream indata; // indata is like cin
int i;
indata.open("persons.txt", ios::in); // opens the file
if(!indata)
{ // file couldn't be opened
cout << "Error: file could not be opened" << endl;
exit(1);
}
int n = 5;
PersonData* p;
p = (PersonData*) malloc (n * sizeof(PersonData));
while ( !indata.eof() )
{
indata >> p[i];
i++;
}
for(i = 0; i < n; ++i)
{
cout << "PersonData [" << i << "] is " << p[i] << endl;
}
return 0;
}
I want to use member function "read" to actually read values into structures defined by PersonData.
My question:
How to read the data from file into PersonId struct which is stored in the PersonData struct??
While reading PersonData[i], I should see it have a struct PersonId with updated value.
I hope my questions are clear now?
You have:
istream& operator >> (istream& is, PersonId &p)
{
is >> p.fId;
return is;
}
missing, after struct PersonId;
You need this to make the is >> fId inside read() work correctly.
Also, fix the cout to use p[i].fId.fId.
Works great!
On a stylistic note, now you're in C++, don't use malloc, use new, and better yet, use a std::vector<>, which will take care of sizing for you.
OK, first some grumbling :-) You say what you want. You wrote how you try. Great. I guess result is not what you expected. But you didn't tell us what is the result you get and why you are disappointed with it. As I look at your code, it shouldn't compile. The problem is here:
istream& PersonData::read(std::istream& is)
{
is >> fId;
return is;
}
I can't see any operator >> defined for PersonId type, and fId is of type PersonId. Am I right? Or maybe there is operator >> defined somewhere and you didn't just paste it into your question? My crystal ball is unclear.
If I guessed properly, the solution is given by Dave Gamble:
istream& operator >> (istream& is, PersonId &p)
{
is >> p.fId;
return is;
}
You wrote "still getting errors in trying to access PersonData". I seems that this time Dave's crystal ball is also unclear, he can't say what problems you have. Neither can I. You have to either provide us details or send us better crystal balls. Maybe you missed his another advice "Also, fix the cout to use p[i].fId.fId." It means, that instead of writing
cout << "PersonData [" << i << "] is " << p[i] << endl;
you should write
cout << "PersonData [" << i << "] is " << p[i].fId.fId << endl;
There can be also another problem - you are not referring to std namespace members consequently - sometimes you write istream, and sometimes you write std::istream, you write endl instead of std::endl. Maybe Koenig's lookup works it out for you, I'm not good at it, but adding std:: prefix may help (of course if this is your problem).