Read file of multiple data types.

C

computerwolf8

I have a file where I know the lines go as follows:

string
long
string
int
int
string
double

it then repeats this sequence multiple times. I can use getline() to
get the data, but I need to be able to use the ints, doubles, and longs
without them being strings or char[]. The strings also have an unknown
amount of spaces in each one, so i can't use >> to get the data. At
least not that I can get to work. Is there a way to get the different
data into variables of the correct types? If there is a way to convert
them after I use getline() that would work too.
 
D

David Harmon

On 26 Oct 2006 23:13:08 -0700 in comp.lang.c++,
(e-mail address removed) wrote,
I can use getline() to
get the data, but I need to be able to use the ints, doubles, and longs

strtod()
strtol()
 
S

Salt_Peter

I have a file where I know the lines go as follows:

string
long
string
int
int
string
double

it then repeats this sequence multiple times. I can use getline() to
get the data, but I need to be able to use the ints, doubles, and longs
without them being strings or char[]. The strings also have an unknown
amount of spaces in each one, so i can't use >> to get the data. At
least not that I can get to work. Is there a way to get the different
data into variables of the correct types? If there is a way to convert
them after I use getline() that would work too.

Write a simple struct with a corresponding member for each of the above
variable types.
I'ld suggest std::string instead of char arrays and leave the numeric
types as they are.
Use a default and a parametized ctor. An overloaded op<< is nice to
have.
Prove that you create a Record in main(). Don't use new.

Then declare a std::vector< Record > where Record represents your new
class.
A good option is to wrap the std::vector in a Container class along
with the filename.
Prove that you can create the Container and
container.push_back(therecord);
An overloaded op<< is nice here too. Display the stored records.
Then code a member function void Container::read() to parse the Records
from your data file (std::ifstream).

A std::stringstream can help you parse a std::string buffer when
std::getlining the numerics.
You need an error checking mechanism, i'ld suggest throwing
std::runtime_errors when checking state of std::ifstream in read(). Use
try-catch block in main() to capture these.

You can use a templated function like so to convert buffer to numbers:

#include <string>
#include <sstream> // for std::stringstream

template < typename T >
T stream_cast(const std::string& r_s)
{
std::stringstream ss;
ss << r_s;
T result;
ss >> result;
return result;
}

int main()
{
std::string s("1.1");
double d = stream_cast< double >(s.data());
std::cout << "d = " << d << std::endl;
}

Sounds daunting but its not that bad.
Got my container working in like 20 minutes.
If any problems, show your code.
The guys in here are a pain in the ass, but they know their stuff, lol.
 
A

Alan Johnson

I have a file where I know the lines go as follows:

string
long
string
int
int
string
double

it then repeats this sequence multiple times. I can use getline() to
get the data, but I need to be able to use the ints, doubles, and longs
without them being strings or char[]. The strings also have an unknown
amount of spaces in each one, so i can't use >> to get the data. At
least not that I can get to work. Is there a way to get the different
data into variables of the correct types? If there is a way to convert
them after I use getline() that would work too.

You could use getline for the strings, and operator >> for everything
else. The only gotcha there is that operator >> won't extract the
newline after the long, ints, or double. So when the next thing you
need to read is a string, the getline will only extract the newline,
rather than the string you were aiming for. This is fixed by putting
in a dummy getline just to grab the newline.

getline(stream, s1);
stream >> l1; getline(stream, eol); // get rid of the newline because
we are reading a string next
getline(stream, s2);
stream >> i1; // no need for getline here because we aren't reading a
string next.
stream >> i2; getline(stream, eol); // get rid of the newline because
we are reading a string next

If you wanted to be very creative, you could exploit the fact that
getline returns a stream to read an entire record in one line:
getline(getline(getline(getline(getline(getline(stream, s1) >> l1,
eol), s2) >> i1 >> i2, eol), s3) >> d1, eol) ;

(Note: You could, but you probably shouldn't).
 

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
474,262
Messages
2,571,049
Members
48,769
Latest member
Clifft

Latest Threads

Top