getline and vector don't work together?

B

Blastbeat

Hello all,
I'm having a hard time extracting elements from a datafile into a STL
vector. The contents of the datafile are as follows:

element1
element2
element3
....

My goal is to read in each element line by line & store each line into
a vector. I want to use a vector because my datafiles will vary in
size. I'm fairly certain that memory is getting over-written in the
while(!OpenAnimations.eof()) loop. I've tried using an sprintf
statement to overcome this, but to no avail. I'm stuck, please help!

I'm using MSVC++ 6.0.

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <fstream>

char read_animation[101];
char vector_data[101];

int main(int argc, char* argv [])
{

// Define Vector
vector <char*> animation_names;

ifstream OpenAnimations("file.csv", ios::in);
if(!OpenAnimations)
{
cerr << "The file failed to open!\n";
exit(1);
}

// Open & Insert animation names into data structure
while(!OpenAnimations.eof())
{
OpenAnimations.getline(read_animation, 100);
sprintf(vector_data, "%s", read_animation);
animation_names.push_back(vector_data);
}

// Search for a string in elements of the vector
start = animation_names.begin();
end = animation_names.end();

for(start; start!=end; start++)
{
if ( strstr(*start, "string"))
{
cout << "Executing string match!\n";
function_to_do_something(*start);
}
}

OpenAnimations.close();
return 0;
}
 
D

deane_gavin

Blastbeat said:
Hello all,
I'm having a hard time extracting elements from a datafile into a STL
vector. The contents of the datafile are as follows:

element1
element2
element3
...

My goal is to read in each element line by line & store each line into
a vector. I want to use a vector because my datafiles will vary in
size. I'm fairly certain that memory is getting over-written in the
while(!OpenAnimations.eof()) loop. I've tried using an sprintf
statement to overcome this, but to no avail. I'm stuck, please help!

I'm using MSVC++ 6.0.

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <fstream>

char read_animation[101];
char vector_data[101];

int main(int argc, char* argv [])
{

// Define Vector
vector <char*> animation_names;

ifstream OpenAnimations("file.csv", ios::in);
if(!OpenAnimations)
{
cerr << "The file failed to open!\n";
exit(1);
}

// Open & Insert animation names into data structure
while(!OpenAnimations.eof())
{
OpenAnimations.getline(read_animation, 100);
sprintf(vector_data, "%s", read_animation);

This overwrites the contents of the vector_data array each time around
the while loop.
animation_names.push_back(vector_data);

Your vector stores pointers_to_char. But each pointer in the vector
points to *the same place*, the start of your vector_data array, which
you have just overwritten.

You are happily using streams and vectors from the standard C++
library. What have you got against std::string? A
std::vector<std::string> would suit you perfectly. Use the freestanding
std::getline function rather than the member function of the stream
class that you are currently using.

<snip>

Gavin Deane
 
?

=?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=

Blastbeat said:
I'm having a hard time extracting elements from a datafile into a STL
vector. The contents of the datafile are as follows:

element1
element2
element3
...

My goal is to read in each element line by line & store each line into
a vector. I want to use a vector because my datafiles will vary in
size. I'm fairly certain that memory is getting over-written in the
while(!OpenAnimations.eof()) loop. I've tried using an sprintf
statement to overcome this, but to no avail. I'm stuck, please help!

I'm using MSVC++ 6.0.

I am not sure whether your compiler will be able to handle this, but
here is a simple solution to your problem taking advantage of STL's
algorithms and iterators:

#include <iterator>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

struct Element
{
string name;
int value;
};

istream& operator>>(istream& is, Element& element)
{
return is >> element.name >> element.value;
}

ostream& operator<<(ostream& os, const Element& element)
{
return os << "Element " << element.name
<< " with value " << element.value;
}

int main()
{
ifstream arq("elements.txt");
vector<Element> v;
copy(istream_iterator<Element>(arq),
istream_iterator<Element>(),
back_inserter(v));
copy(v.begin(),
v.end(),
ostream_iterator<Element>(cout, "\n"));
}

Best regards,
 
?

=?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=

Ney said:
I am not sure whether your compiler will be able to handle this, but
here is a simple solution to your problem taking advantage of STL's
algorithms and iterators:

Excuse me, I forgot to include the contents of the input file I used
with the program. Here it is:

first 111
second 222
third 333
fourth 444
fifth 555

Regards,
 
O

Old Wolf

Blastbeat said:
Hello all,
I'm having a hard time extracting elements from a datafile into a
STL vector.

// Open & Insert animation names into data structure
while(!OpenAnimations.eof())

As well as what deane_ga said: this is a recipe for disaster.
If the read fails for any reason other than eof() you will get
an infinite loop, and if it doesn't, you will probably read
the last line twice. Please read the newsgroup FAQ on correct
use of EOF.
{
OpenAnimations.getline(read_animation, 100);
sprintf(vector_data, "%s", read_animation);
animation_names.push_back(vector_data);
}

Your loop should be:
while( OpenAnimations.getline(read_animation, 100) )
{
sprintf....

Also, note that you can cause a buffer overflow with the
sprintf. If you really must use char arrays instead of
std::string, do "%.100s".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,999
Latest member
MakersCBDGummiesReview

Latest Threads

Top