Parsing Input with cin

M

Mike Copeland

How can I use cin to "reverse" the logic below?:

ostringstream oss2;
oss2 << cNoEvts << setfill('_') << setw(24) << left << EvLst1 << right
<< setfill('0') << setw(2) << nDivis
<< setw(4) << nBatch << setw(6) << sEntId << cEntIdx << setw(5)
<< sEnDate << cEntType << setw(5) << sTDate1 << cTCode1 << setw(5)
<< sTDate2 << cTCode2 << cRecCode << "1>" << endl;

That is, I format an output line and write it to a text file, but I
also need to read that file and parse the line's data fields according
to the format I create above. (I don't have any redesign option,
because the data file format is fixed and can't be changed - to comma-
separated-values that can be parsed.) Also, the data line is much more
complex than this code snippet shows, so there's a _lot_ of fixed-field
formatting being done here (50+ fields, >300 characters in the line).
I used to accomplish this this in the C-style: a very large sprintf
call and a single text line "read", followed by individual field parsing
and conversions (numeric fields, strings, individual characters, etc.).
I am trying here to use more state-of-the-art coding (without knowing if
there will be a performance hit or not...) - perhaps I'm taking the
wrong approach... Please advise. TIA
 
I

Ian Collins

How can I use cin to "reverse" the logic below?:

ostringstream oss2;
oss2<< cNoEvts<< setfill('_')<< setw(24)<< left<< EvLst1<< right
<< setfill('0')<< setw(2)<< nDivis
<< setw(4)<< nBatch<< setw(6)<< sEntId<< cEntIdx<< setw(5)
<< sEnDate<< cEntType<< setw(5)<< sTDate1<< cTCode1<< setw(5)
<< sTDate2<< cTCode2<< cRecCode<< "1>"<< endl;

That is, I format an output line and write it to a text file, but I
also need to read that file and parse the line's data fields according
to the format I create above. (I don't have any redesign option,
because the data file format is fixed and can't be changed - to comma-
separated-values that can be parsed.) Also, the data line is much more
complex than this code snippet shows, so there's a _lot_ of fixed-field
formatting being done here (50+ fields,>300 characters in the line).
I used to accomplish this this in the C-style: a very large sprintf
call and a single text line "read", followed by individual field parsing
and conversions (numeric fields, strings, individual characters, etc.).
I am trying here to use more state-of-the-art coding (without knowing if
there will be a performance hit or not...) - perhaps I'm taking the
wrong approach... Please advise. TIA

It's not pretty, but something like:

template <typename T> T read( std::istream& in, unsigned width )
{
std::stringstream ss;
char buffer[32];

in.read( buffer, width );
buffer[width] = '\0';

char* p = buffer;

while( *p && *p == '_' ) ++p;

ss << p;

T t;

ss >> t;

return t;
}

would do the trick for each field.
 
J

James Kanze

How can I use cin to "reverse" the logic below?:
ostringstream oss2;
oss2 << cNoEvts << setfill('_') << setw(24) << left << EvLst1 << right
<< setfill('0') << setw(2) << nDivis
<< setw(4) << nBatch << setw(6) << sEntId << cEntIdx << setw(5)
<< sEnDate << cEntType << setw(5) << sTDate1 << cTCode1 << setw(5)
<< sTDate2 << cTCode2 << cRecCode << "1>" << endl;

Without knowing the "logic" of this code, it's impossible to
say. It could very well be impossible (if, for example, cTCode2
and cRecCode are int's).
That is, I format an output line and write it to a text file, but I
also need to read that file and parse the line's data fields according
to the format I create above. (I don't have any redesign option,
because the data file format is fixed and can't be changed - to comma-
separated-values that can be parsed.) Also, the data line is much more
complex than this code snippet shows, so there's a _lot_ of fixed-field
formatting being done here (50+ fields, >300 characters in the line).

Fixed width fields are usualy best handled by reading them into
a char array (using read), then converting this to a string; if
the target type isn't std::string, use the buffer to initialize
an istrstream, and read from it. Something like:

char field[ fieldSize ];
if ( source.read( field, fieldsize ) ) {
std::string fieldValue( field, fieldSize );
// ...
// or
std::istrstream s( field, fieldSize );
s >> fieldValue;
// ...
}
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top