parsing with std::istringstream.

D

Dave Townsend

Hi,

I have to read some memory data from a stream. This would be in the
following format, for example:

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07

that is i have 8 values on a line, separated by whitespace, except the last
line which might not have a full complement of data.

I am reading the line into a istreamstring object and then trying to read
off each data item.

char ch1
char ch2;
unsigned short val;

istr >> ch1;
// check that I got something...

istr >> ch2;
// check that I got something...


istr >> val;

Then I check that I've got the "0x" piece:

if ( ch1 != '0' || ch2 != 'x') return error.....


So, with all this functionality in the stream classes, isn't there a way to
specify a certain pattern in the data, that is, I want to "expect" '0x',
then an integer ?
I seem to remember that scanf could do something like that, that is scan two
characers, then an integer.

Any piece of code or places to look would be welcomed.

dave.
 
K

Kai-Uwe Bux

Dave said:
Its a hex represntation of a 1 byte integer.

Wow, so that's what happens when a top-poster meets a full-quoting
bottom-poster: question and answer get maximally separated. (Of course, the
bottom poster is right.)


As for the original question, here is something to ponder:


#include <iostream>
#include <sstream>
#include <iomanip>

int main ( void ) {
std::istringstream source ( "0x12 0x3a" );
short int a;
short int b;
if ( source >> std::hex >> a >> std::hex >> b ) {
std::cout << "a = " << a << '\n'
<< "b = " << b << '\n';
}
}



Best

Kai-Uwe Bux
 
J

James Kanze

I have to read some memory data from a stream. This would be in the
following format, for example:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
that is i have 8 values on a line, separated by whitespace, except the last
line which might not have a full complement of data.
I am reading the line into a istreamstring object and then trying to read
off each data item.
char ch1
char ch2;
unsigned short val;
istr >> ch1;
// check that I got something...
istr >> ch2;
// check that I got something...
istr >> val;
Then I check that I've got the "0x" piece:
if ( ch1 != '0' || ch2 != 'x') return error.....
So, with all this functionality in the stream classes, isn't
there a way to specify a certain pattern in the data, that is,
I want to "expect" '0x', then an integer ?

You'd need a custom manipulator, but it's useful in general, and
not too difficult to write.
I seem to remember that scanf could do something like that,
that is scan two characers, then an integer.
Any piece of code or places to look would be welcomed.

The first question is whether you want to require the 0x, or
just accept it and ignore it if it is present. In the first
case, just setting the base to hex will do the trick; the hex
numeric format allows an optional "0x" or "0X" prefix. In the
second, the solution I'd use would be a regular expression
(boost::regex) on the entire line, before parsing it. Note that
neither the solution above, nor scanf, really work for rigorous
checking, because both allow whitespace between the "0x" and the
following digits. And while it's possible to write a
manipulator which ensures that the "0x" is immediately followed
by a hex digit, this really isn't what manipulators are designed
for; there's something unexpected about a manipulator which may
modify iostate, except for eofbit (although I've used them in
special cases).
 

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
474,201
Messages
2,571,048
Members
47,651
Latest member
VeraPiw932

Latest Threads

Top