Sign in to follow this  
boogyman19946

getline won't accept arguments

Recommended Posts

boogyman19946    1487
Ok, for a short little exercise, I decided to brush off the dust on C++ and try out SDL while at it in a fun game of Hangman. Unfortunately, I have a little problem compiling because the compiler is giving me errors that I don't think should be occurring. I was looking up the ifstream function for file reading and the Cplusplus site suggested that I could use the global getline function to retrieve a line in a string object. So all that being dandy and what not, I wrote the following.

[code]


std::ifstream wordListFile("wordList.txt", std::ifstream::in);
std::list<std::string> temporaryWordList();
if(wordListFile.good()) {
while(!wordListFile.eof()) {
std::string tempString();
std::getline(wordListFile, tempString);
if(wordListFile.gcount() > 0) {
temporaryWordList.push_back(tempString);
mWordListSize++;
}
}
} else {
std::cout << "Word list could not be open." << std::endl;
}
wordListFile.close();
[/code]


From what I understand, the first argument is a reference to an istream type object and the second a reference to a string. There I am passing ifstream (I assume the function will take subclasses of istream as well) and tempString but the compiler throws at me the following error:

[code]

1>e:\documents and settings\administrator\my documents\visual studio 2010\projects\hangman\hangman\hangman.cpp(16): error C2665: 'std::getline' : none of the 2 overloads could convert all the argument types
1> e:\program files\microsoft visual studio 10.0\vc\include\string(448): could be 'std::basic_istream<_Elem,_Traits> &std::getline<char,std::char_traits<char>,std::allocator<_Ty>>(std::basic_istream<_Elem,_Traits> &&,std::basic_string<_Elem,_Traits,_Ax> &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ty=char,
1> _Ax=std::allocator<char>
1> ]
1> e:\program files\microsoft visual studio 10.0\vc\include\string(479): or 'std::basic_istream<_Elem,_Traits> &std::getline<char,std::char_traits<char>,std::allocator<_Ty>>(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Ax> &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ty=char,
1> _Ax=std::allocator<char>
1> ]
1> while trying to match the argument list '(std::ifstream, overloaded-function)'
[/code]

That's not the only problem. The compiler also complains about the line:

[code]
temporaryWordList.push_back(&tempString);
[/code]

saying

[code]
error C2228: left of '.push_back' must have class/struct/union
[/code]

I can't figure out these problems for the life of me. Should I be reviewing my C++ basics or am I right?

EDIT: Nevermind. It turns out that I am indeed dumb. Neither std::string tempString nor the temporaryWordList were supposed to have parentheses at the end of the declaration. I'm thinking back to Java (where the variable would be a reference and it would be null without explicitly creating the object).

Share this post


Link to post
Share on other sites
bbr125    109
Try changing:
std::string tempString();

to

std::string tempString;


And about this:

temporaryWordList.push_back(&tempString);


It's a list of strings. Not a list of string pointers. So you just want to:

temporaryWordList.push_back(tempString);





Share this post


Link to post
Share on other sites
boogyman19946    1487
Yeah I figured it out, thanks though, that was the actual problem. I'm a little bit tired and I was modifying the code while I was typing the response so where I quoted temporaryWordList.push_back(&tempString), the list was indeed actually taking pointers, but I speculated that once the next loop iteration starts, the string would've been obsolete and the pointer would've been invalidated so I modified the code to take non-pointers and forgot to update both code quotations. The error of the temporaryWordList.push_back(tempString) was actually the same as the one of the string: I put parentheses after creating the list variable.

Share this post


Link to post
Share on other sites
rip-off    10976
If you look closely at your original declarations of temporaryWordList and tempString, you'll see they actually resemble function declarations. Indeed, this is what the compiler treats them as.

Some other things you can clean up in your code:
[code]
std::ifstream in("wordList.txt", std::ifstream::in);
if(!wordListFile)
{
std::cout << "Word list could not be open." << std::endl;
// Early returns get special cases out of the way, so you can concentrate on the normal case
return false;
}

// Describing local variables as "temp" or "temporary" doesn't help too much.
std::list<std::string> words;
std::string line;

// This is an idiomatic loop for reading lines from a std::istream
while(std::getline(in, line))
{
words.push_back(line);
// When the loop finishes, we can simply assign mWordListSize using std:list<>::size()
// mWordListSize++;
}

// In addition to what was said above, do you even need to store the size of this list separately?
// Would it not make more sense to store the list itself as a member?
//
// If you only want the size, why bother saving all the strings in a list?
mWordListSize = words.size();

// std::fstream objects close themselves.
// wordListFile.close();
[/code]

Share this post


Link to post
Share on other sites
boogyman19946    1487
I'll be honest, I've wrote some things tonight which are a shame to admit I have. As I was writing the code I decided for some odd reason to use a pointer to std::string to represent the word list but I also wanted a modifiable word list. Through an apparently very sophisticated process I've concluded that the best approach is not to use a list but rather to populate that list, harnessing the size of the word list, and then copy all the words to a dynamic array, because dynamic arrays are way cooler than lists. I've done a lot of silly mistakes writing all this code (yet I see that wordListFile is an undeclared identifier in your code... mwuahaha :D).

I best stop programming this late. The ironic thing is, I felt like I was writing much more fluently not using my brain than when I do :)

Share this post


Link to post
Share on other sites
rip-off    10976
That is OK, we all write poor code from time to time. My main point was to show how simple it can be to read lines from std::ifstream, rather than your much more complex version of nested loops and conditionals.

Share this post


Link to post
Share on other sites
boogyman19946    1487
[quote name='rip-off' timestamp='1311587261' post='4839919']
That is OK, we all write poor code from time to time. My main point was to show how simple it can be to read lines from std::ifstream, rather than your much more complex version of nested loops and conditionals.
[/quote]

Ok, I know I'm reviving a dead thread, but if you're reading this rip-off, I just want to say that you're totally awesome for writing that post above (the one with simplified nested loops). I've went into my pathfinding code and cleaned it up a bit, and found so many bugs it's not even funny, not to mention it made everything so much cleaner that polishing the code to work like it's supposed to wasn't even a challenge. Thanks a whole bunch! I'd give you a +5 but I'm only allowed 1 >.>

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this