473,508 Members | 2,282 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

why am I getting the C version of getline()?

I seem to be having a problem with getline(). I have tried to find it
on
google, but I'm not seeing the answer. The goal of this section of
code
is simply to read in a line from a file to a string according to the
conditions of the do...while statement.

/////code

void populate( vector<string>& unplayed_anagrams, string& word, const
ifstream& dict_word_list )
{
const int max_size = word.size() + 1;
int letters_left;
char word_array[max_size];
char test_word_array[max_size];
string measure_word = " ";
vector<intused_letters;
vector<int>::iterator iter;

used_letters.clear();
memset( test_word_array, '\0', max_size);
memset( word_array, '\0', max_size);
strcpy( word_array, word.c_str() );

cout << "Please wait... Populating the arrays." << endl;

while( !dict_word_list.eof() )
{
letters_left = (max_size - 1 ) ;
do
{
getline( dict_word_list, measure_word ); //<-This is the
offending code
}
while((measure_word.size() word.size() && measure_word.size() <
3) || measure_word == word);

\\\\\code

I have another section of code that does almost the same thing, with
the
exception that it works.

/////code

void load_words( string& word, ifstream& dict_file )
{
vector<stringtemp_vector;
int random_num = 0;
int temp_size = 0;
string line = " ";

temp_vector.clear();

while( word.size() < 6 )
{
while( !dict_file.eof() )
{
getline( dict_file, line );
temp_vector.push_back( line );
++temp_size;
}
random_num = ( rand() % temp_size );
word = temp_vector[random_num];
}
}

\\\\\code

When I compile the code, I get a compile time error pointing to the
getline() in the first chunk of code.

/////error

jaag.cc: In function 'void
populate(std::vector<std::basic_string<char,
std::char_traits<char>, std::allocator<char,
std::allocator<std::basic_string<char, std::char_traits<char>,
std::allocator<char &, std::string&, const std::ifstream&)':
jaag.cc:126: error: invalid conversion from 'void*' to 'char**'
jaag.cc:126: error: cannot convert 'std::string' to 'size_t*' for
argument '2' to '__ssize_t getline(char**, size_t*, FILE*)'

\\\\\error

I was using these includes:

/////code

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <fstream>
#include <string>

\\\\\code

as best as I can figure it I am getting the C version of getline() in
the first one and the C++ version in the second one. I can't figure
it
out. That's not what I need. I want them both to be C++. Any help on
this
would be greatly appreciated.

Thanks

PS I am using gcc-4.1.2 on amd64-gentoo-linux. If you need, I can
post
the code that is calling these functions. Thanks again.

Mar 10 '07 #1
13 2286
th*************@gmail.com wrote:
I seem to be having a problem with getline(). I have tried to find it
on
google, but I'm not seeing the answer. The goal of this section of
code
is simply to read in a line from a file to a string according to the
conditions of the do...while statement.

/////code

void populate( vector<string>& unplayed_anagrams, string& word, const
ifstream& dict_word_list )
Here is the error, drop the const

void populate( vector<string>& unplayed_anagrams, string& word,
ifstream& dict_word_list )

And of course in *both* your functions, you should have istream not
ifstream. Using istream in the function means the function can be used
with any input stream, i.e. ifstream, fstream, istringstream,
stringstream, cin, plus any others you care to define. Why limit your
function to reading files only?

john
Mar 10 '07 #2
Thank you - it worked. I could have swore I tried that. *smacks self
in head*. Anyway, thanks. As for the function - I have no use for
anymore functionality. "Do one thing and do it well" from what I
understand. If I ever need it again, I should know more about it and
it shouldn't be too hard to modify.

Mar 10 '07 #3
th*************@gmail.com wrote:
Thank you - it worked. I could have swore I tried that. *smacks self
in head*. Anyway, thanks. As for the function - I have no use for
anymore functionality. "Do one thing and do it well" from what I
understand. If I ever need it again, I should know more about it and
it shouldn't be too hard to modify.
LOL, all you have to do is delete the 'f' from ifstream, not too hard?
And it's a good habit to get into, shows you understand one of the key
points of OO programming.

john
Mar 10 '07 #4
On Mar 10, 2:32 pm, John Harrison <john_androni...@hotmail.comwrote:
theronnights...@gmail.com wrote:
Thank you - it worked. I could have swore I tried that. *smacks self
in head*. Anyway, thanks. As for the function - I have no use for
anymore functionality. "Do one thing and do it well" from what I
understand. If I ever need it again, I should know more about it and
it shouldn't be too hard to modify.

LOL, all you have to do is delete the 'f' from ifstream, not too hard?
And it's a good habit to get into, shows you understand one of the key
points of OO programming.

john
I'll mark that one to you. I am still real new to anything past the
most basic aspects of C++. You say istream can be bound to any input
stream? I assume I don't have to set ios:: Correct?

Mar 10 '07 #5
th*************@gmail.com wrote:
On Mar 10, 2:32 pm, John Harrison <john_androni...@hotmail.comwrote:
>>theronnights...@gmail.com wrote:
>>>Thank you - it worked. I could have swore I tried that. *smacks self
in head*. Anyway, thanks. As for the function - I have no use for
anymore functionality. "Do one thing and do it well" from what I
understand. If I ever need it again, I should know more about it and
it shouldn't be too hard to modify.

LOL, all you have to do is delete the 'f' from ifstream, not too hard?
And it's a good habit to get into, shows you understand one of the key
points of OO programming.

john


I'll mark that one to you. I am still real new to anything past the
most basic aspects of C++. You say istream can be bound to any input
stream? I assume I don't have to set ios:: Correct?
Correct, when you declare a stream variable, you have to say ifstream,
stringstream or whatever kind of stream it is.

But when you write a function that reads some input you should always
declare the stream parameter as istream&, as in

void some_function_that_reads(istream& the_stream_to_read)
{
...
}

That way the function will work with any kind of input stream. Once you
understand, it's a no-brainer.

Technically the reason is that ifstream, fstream, istringstream, cin
etc. all inherit from istream, so any of them will bind to to istream&.

john
Mar 10 '07 #6
John Harrison wrote:
th*************@gmail.com wrote:
>On Mar 10, 2:32 pm, John Harrison <john_androni...@hotmail.comwrote:
>>theronnights...@gmail.com wrote:

Thank you - it worked. I could have swore I tried that. *smacks self
in head*. Anyway, thanks. As for the function - I have no use for
anymore functionality. "Do one thing and do it well" from what I
understand. If I ever need it again, I should know more about it and
it shouldn't be too hard to modify.
LOL, all you have to do is delete the 'f' from ifstream, not too hard?
And it's a good habit to get into, shows you understand one of the key
points of OO programming.

john

I'll mark that one to you. I am still real new to anything past the
most basic aspects of C++. You say istream can be bound to any input
stream? I assume I don't have to set ios:: Correct?

Correct, when you declare a stream variable, you have to say ifstream,
stringstream or whatever kind of stream it is.

But when you write a function that reads some input you should always
declare the stream parameter as istream&, as in

void some_function_that_reads(istream& the_stream_to_read)
{
...
}

That way the function will work with any kind of input stream. Once you
understand, it's a no-brainer.

Technically the reason is that ifstream, fstream, istringstream, cin
etc. all inherit from istream, so any of them will bind to to istream&.

john
Same goes for ostream& as well of course.

john
Mar 10 '07 #7
On Mar 10, 2:42 pm, John Harrison <john_androni...@hotmail.comwrote:
John Harrison wrote:
theronnights...@gmail.com wrote:
On Mar 10, 2:32 pm, John Harrison <john_androni...@hotmail.comwrote:
>theronnights...@gmail.com wrote:
>>Thank you - it worked. I could have swore I tried that. *smacks self
in head*. Anyway, thanks. As for the function - I have no use for
anymore functionality. "Do one thing and do it well" from what I
understand. If I ever need it again, I should know more about it and
it shouldn't be too hard to modify.
>LOL, all you have to do is delete the 'f' from ifstream, not too hard?
And it's a good habit to get into, shows you understand one of the key
points of OO programming.
>john
I'll mark that one to you. I am still real new to anything past the
most basic aspects of C++. You say istream can be bound to any input
stream? I assume I don't have to set ios:: Correct?
Correct, when you declare a stream variable, you have to say ifstream,
stringstream or whatever kind of stream it is.
But when you write a function that reads some input you should always
declare the stream parameter as istream&, as in
void some_function_that_reads(istream& the_stream_to_read)
{
...
}
That way the function will work with any kind of input stream. Once you
understand, it's a no-brainer.
Technically the reason is that ifstream, fstream, istringstream, cin
etc. all inherit from istream, so any of them will bind to to istream&.
john

Same goes for ostream& as well of course.

john
Nice - thanks for that very valuable lesson. I will have to make sure
I use that.

I still have a problem though. I put a few cout statements in as
visual checks, but it is still failing on the getline statement. No
compiler error, but the cout that should show what is in the string I
am reading into says nothing. . One line above the getline() is
another cout that does display what it is supposed to.

/////code

void populate( vector<string>& unplayed_anagrams, string& word,
ifstream& word_file )
{
const int max_size = word.size() + 1;
int letters_left;
char word_array[max_size];
char test_word_array[max_size];
string measure_word;
vector<intused_letters;
vector<int>::iterator iter;

used_letters.clear();
memset( test_word_array, '\0', max_size);
memset( word_array, '\0', max_size);
strcpy( word_array, word.c_str() );
cout << "word_array in populate() is: "; //<-Debug statement
for(int z = 0; z < max_size; ++z) //<-Debug statement
{
cout << word_array[z]; //<-Debug statement
}
cout << endl; //<-Debug statement
cout << "Please wait... Populating the arrays." << endl;

do
{
letters_left = (max_size - 1 ) ;
cout << "\nletters_left is: " << letters_left << endl; //<-Debug
statement
do
{
if( word_file.is_open() ) //<-Debug statement
cout << "The word_file is open." << endl; //<-Debug statement -
works
getline( word_file, measure_word ); //<-Problem
cout << "\nmeasure_word in populate() is: " << measure_word <<
endl; //<-Debug statement - doesn't work
}
while( ( measure_word.size() word.size() && measure_word.size() <
3 ) || measure_word == word );

strcpy( test_word_array, measure_word.c_str() );

I went back with the ifstream in the declaration though - is_open()
doesn't work otherwise.

Mar 10 '07 #8
Sorry bout quoted text above.

Mar 10 '07 #9
>
Nice - thanks for that very valuable lesson. I will have to make sure
I use that.

I still have a problem though. I put a few cout statements in as
visual checks, but it is still failing on the getline statement. No
compiler error, but the cout that should show what is in the string I
am reading into says nothing. . One line above the getline() is
another cout that does display what it is supposed to.
The only explanation is that word_file isn't in the state you think it
is. Possibly it's already at the end of file. Possibly you were reading
something before and got an error. Possibly the file simply isn;t
positioned where you think it is. In any case it must be something about
how you used word_file before you call the populate function. Perhaps
you could post that code.
/////code

void populate( vector<string>& unplayed_anagrams, string& word,
ifstream& word_file )
{
const int max_size = word.size() + 1;
int letters_left;
char word_array[max_size];
char test_word_array[max_size];
Neither of the above two line are legal C++ because max_size is not a
compile time constant. I know it's a constant, but it's not a compile
time constant as the value must be worked out at runtime.

There is one compiler I know which allows this kind of code, but if you
try this code on a different compiler you will likely get an error.

john
Mar 10 '07 #10
As you can tell I am trying to do a simple anagram game for my fiance.
She loves them and I thought it would be an excellent learning
exercise. I was very right, but this I can't figure out. I know there
are a million better ways to this, but like I said, I am on a quest to
learn by this. This is the full code as it runs (sorry about the
length):

/////code

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <fstream>
#include <string>

using namespace std;

void test_functions();
void test2(vector<string>& unplayed, vector<string>& played);
void load_words( string& word, istream& dict_file ); //Loads the words
from the dict_file to memory and chooses a game word
void populate( vector<string>& unplayed_anagrams, string& word,
ifstream& word_file );

void test_functions()
{
srand(time(0));
vector<stringunplayed_anagrams;
vector<stringplayed_anagrams;
string word;
ifstream file;
char again = 'y';

file.open("test_list");
unplayed_anagrams.clear();
played_anagrams.clear();

load_words(word, file);
cout << "\nChosen word is: " << word << endl;

populate(unplayed_anagrams, word, file); //<- Everthing is fine to
here

test2(unplayed_anagrams, played_anagrams);

string test_word;
here:
int y = 1;
while( y == 1 )
{
cout << "\nChoose an anagram: ";
getline(cin, test_word);
y = anagram_test(unplayed_anagrams, played_anagrams, test_word);
if( y == 1)
{
cout << "Anagram is not valid." << endl;
}
else
{
cout << "Anagram should be valid." << endl;
}
}
test2(unplayed_anagrams, played_anagrams);
cout << "\nTest more? ";
cin.get(again);
cin.ignore(1, '\n');
if( again == 'y' )
{
goto here;
}

}

void test2(vector<string>& unplayed, vector<string>& played)
{
vector<string>::iterator iter;

cout << "unplayed_anagrams are:" << endl;
int x = 1;
for( iter = unplayed.begin(); iter != unplayed.end(); ++iter)
{
cout << x << ". " << *iter << endl;
}
x = 1;
cout << "\nplayed_anagrams are:" << endl;
for( iter = played.begin(); iter != played.end(); ++iter)
{
cout << x << ". " << *iter << endl;
}
}
void populate( vector<string>& unplayed_anagrams, string& word,
ifstream& word_file )
{
const int max_size = word.size() + 1;
int letters_left;
char word_array[max_size];
char test_word_array[max_size];
string measure_word;
vector<intused_letters;
vector<int>::iterator iter;

used_letters.clear();
memset( test_word_array, '\0', max_size);
memset( word_array, '\0', max_size);
strcpy( word_array, word.c_str() );
cout << "word_array in populate() is: ";
for(int z = 0; z < max_size; ++z)
{
cout << word_array[z];
}
cout << endl;
cout << "\nPlease wait... Populating the arrays." << endl;

do
{
letters_left = (max_size - 1 );
cout << "\nletters_left is: " << letters_left << endl; //<- Works
here
do
{
if( word_file.is_open() )
cout << "The word_file is open." << endl; //<-this displays
getline( word_file, measure_word );
cout << "\nmeasure_word in populate() is: " << measure_word <<
endl; //<-This does not
}
while( ( measure_word.size() word.size() && measure_word.size() <
3 ) || measure_word == word );

strcpy( test_word_array, measure_word.c_str() );

for( int x1 = 0; x1 < max_size; ++x1)
{
for( int x2 = 0; x2 < max_size; ++x2 )
{
if( test_word_array[x2] == word_array[x1] )
{
for( iter = used_letters.begin(); iter != used_letters.end();
++iter )
{
if( x2 != *iter )
{
continue;
}
else
{
break;
}
}
if( iter == used_letters.end() )
{
used_letters.push_back(x1);
--letters_left;
}
else
{
continue;
}

}
else
{
continue;
}
}
}
if( letters_left == 0 )
{
string blah = test_word_array;
unplayed_anagrams.push_back(blah);
}
else
{
continue;
}
}
while( !word_file.eof() );
cout << "\nDone." << endl;
}
void load_words( string& word, istream& dict_file )
{
vector<stringtemp_vector;
int random_num = 0;
int temp_size = 0;
string line = " ";

temp_vector.clear();

while( word.size() < 6 )
{
while( !dict_file.eof() )
{
getline( dict_file, line );
cout << line << endl;
temp_vector.push_back( line );
++temp_size;
}
random_num = ( rand() % temp_size );
word = temp_vector[random_num];
}
}

//irrelevant code removed

int main()
{
test_functions();
return 0;
}
Mar 10 '07 #11
th*************@gmail.com wrote:
As you can tell I am trying to do a simple anagram game for my fiance.
She loves them and I thought it would be an excellent learning
exercise. I was very right, but this I can't figure out. I know there
are a million better ways to this, but like I said, I am on a quest to
learn by this. This is the full code as it runs (sorry about the
length):
No problem. The issue is that you read the "test_list" all the way to
the end of file in load_words. It's still at the end of file when you
call populate. Even worse when you read past the end of file that puts
the stream into an error state. When a stream is in an error state
nothing works until you clear the error state.

Now I'm not sure exactly what you are trying to do, but I would guess
that you want to go back to the beginning of the file before you call
the populate function, so that populate starts reading from the
beginning of "test_list". If so then see the additional code below
>
/////code

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <fstream>
#include <string>

using namespace std;

void test_functions();
void test2(vector<string>& unplayed, vector<string>& played);
void load_words( string& word, istream& dict_file ); //Loads the words
from the dict_file to memory and chooses a game word
void populate( vector<string>& unplayed_anagrams, string& word,
ifstream& word_file );

void test_functions()
{
srand(time(0));
vector<stringunplayed_anagrams;
vector<stringplayed_anagrams;
string word;
ifstream file;
char again = 'y';

file.open("test_list");
unplayed_anagrams.clear();
played_anagrams.clear();

load_words(word, file);
cout << "\nChosen word is: " << word << endl;
// load_words has placed file in an error state
// since it read to end of file, so first thing
// to do is clear the error state
file.clear();

// now we want to start reading from the beginning
// of the file again, so seek to start of file
file.seekg(0, ios_base::beg);

// now (hopefully) everything should be OK
populate(unplayed_anagrams, word, file); //<- Everthing is fine to
here
john
Mar 10 '07 #12
You are so absolutely the man. That solved it all. Thanks for the
lesson. I'll take it to heart. lol such a simple solution. Thanks
again.
Raymond

Mar 10 '07 #13
In article <11**********************@j27g2000cwj.googlegroups .com>,
th*************@gmail.com says...

[ ... ]
while( !word_file.eof() );
[ ... ]
while( !dict_file.eof() )
I haven't looked through all your code, but these jumped out at first
glance. For all practical purposes, a loop like this can never work
correctly. whatever.eof() only returns true when you attempt to read
from the file but you've _already_ read all the input. Usually, you need
to read the input, and check the return from that attempt to read, to
see whether it encountered the end of the file or not. A typical
(correct) loop would looks something like:

while (getline(dict_file, line)) {
cout << line << endl;
temp_vector.push_back(line);
++ temp_size;
}

Since it looks like you have quite a few places that you read strings a
line at a time, I'd consider writing a small proxy class that works that
way:

class line {
std::string data;
public:
operator std::string() const { return data; }

friend std::istream &operator>>(std::istream &is, line &l) {
return std::getline(is, l.data);
}
};

This allows you to read a line at a time using the normal stream
extraction operator (>>). stream_iterators use insertion and extraction
operators, so once you support them, you can use standard algorithms for
quite a bit of what you're doing. For example, I'd rewrite your
load_words something like this:

string load_words(string &word, istream &dict_file) {
vector<stringtemp_vector;

// read data from file to vector:
copy(istream_iterator<line>(dict_file),
istream_iterator<line>(),
back_inserter(temp_vector));

// write data from vector to cout
std::copy(temp_vector.begin(), temp_vector.end(),
ostream_iterator<string>(std::cout, "\n"));

// return randomly chosen word
return temp_vector[rand() % temp_vector.size()];
}

I didn't look at it in detail, but I did notice that part of your code
uses strcpy -- chances are that you'd be better off using std::string
instead, in which case you can just use the assignment operator.

I should also add that if you're going to call load_words very often
(like anything more than once), it would generally be quite a bit better
to read the file only once during initialization, and from then on use
the data from memory.

As a general rule, I'd also advise that when you post code like this,
you provide at least some minimal explanation of 1) what you want it to
do, and 2) what it's not doing that you want it to (or what it's doing
that you don't want). It might be reasonable to assume people remember
your post from a few days ago in a newsgroup that gets only a half dozen
posts a week (or something on that order), but in a newsgroup this busy,
most people have to rely almost entirely on _this_ post to figure out
what it's about.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Mar 10 '07 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
3537
by: Vikram | last post by:
Hi, I don't remember if it happened previously, but nowadays I'm having problem with using cin.getline function and cin>> function simultaneously. I have Visual Studio 6. If I use cin.getline...
4
10949
by: Surya Kiran | last post by:
Hi all, I'm facing a wierd problem. I've a file, which is getting updated every now and then. and i'm having another program, which monitors the file. I've to read the file line by line, and in...
5
7726
by: vknid | last post by:
Hello, I have a question. Its probably a very newbish question so please be nice hehe. =D I have been reading through C++ Programming Fundamentals, and have come a crossed an example program...
1
2133
by: ma740988 | last post by:
Consider: ifstrem MyFile("extractMe.txt"); string Str; getline(MyFile, Str); getline above extracts the contents of MyFile and place into the string object. Deduced using FROM/TO logic I...
10
5590
by: Skywise | last post by:
I keep getting the following error upon compiling: c:\c++ files\programs\stellardebug\unitcode.h(677) : error C2664: 'class istream &__thiscall istream::getline(char *,int,char)' : cannot convert...
14
3856
by: KL | last post by:
I am so lost. I am in a college course for C++, and first off let me state I am not asking for anyone to do my assignment, just clarification on what I seem to not be able to comprehend. I have a...
18
8224
by: Amadeus W. M. | last post by:
I'm trying to read a whole file as a single string, using the getline() function, as in the example below. I can't tell what I'm doing wrong. Tried g++ 3.2, 3.4 and 4.0. Thanks! #include...
3
3674
by: dei3cmix | last post by:
Hey, I am having a problem with a program I am working on. Basically, the first part of the program gets input from a file using cin.getline. Then the second part, (still in the same main as the...
2
3965
by: kellymart87 | last post by:
//remain.cpp #include <iostream.h> #include <conio.h> int main() getline ()
0
7333
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7061
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7502
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5637
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5057
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4716
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3194
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1566
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
428
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.