read fixed width numbers from stringstream

K

klaus hoffmann

Is it possible to convert 2 characters from a stringstream to an integer without
using an intermediate a 2-bytes string ? The following fragment doesn't work

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <string>
using namespace std;

int main()
{
istringstream lb("200");
int ct;
lb>>setw(2)>>ct;
cout<<ct;
return 0;
}
 
H

Howard Hinnant

klaus hoffmann said:
Is it possible to convert 2 characters from a stringstream to an integer
without
using an intermediate a 2-bytes string ? The following fragment doesn't work

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <string>
using namespace std;

int main()
{
istringstream lb("200");
int ct;
lb>>setw(2)>>ct;
cout<<ct;
return 0;
}

Yes. You can derive from std::num_get and override the appropriate
do_get virtual functions to read/convert 2 digit integers. Then you
need to create a locale with this derived facet and imbue your
istringstream with that locale.

Having implemented num_get myself, if I needed to do what you're doing,
I'd just use an intermediate 2-byte string.

-Howard
 
K

klaus hoffmann

Howard said:
Yes. You can derive from std::num_get and override the appropriate
do_get virtual functions to read/convert 2 digit integers. Then you
need to create a locale with this derived facet and imbue your
istringstream with that locale.

Having implemented num_get myself, if I needed to do what you're doing,
I'd just use an intermediate 2-byte string.

-Howard

Thank you. So it seems okay to even use sscanf in this case.
sicerely
Klaus
 
H

Howard

... Then you
need to create a locale with this derived facet and imbue your
istringstream with that locale.

Hi Howard,

this is the other Howard. :)

I'm not sure what that sentence above means. What's a "facet"? And
what's a "locale"? And how do you "imbue" a stream with it? Sorry, but I
just don't recognize those terms (at least not in the context of C++
programming).

Thanks,
-Howard
 
S

Siemel Naran

I'm not sure what that sentence above means. What's a "facet"? And
what's a "locale"? And how do you "imbue" a stream with it? Sorry, but I
just don't recognize those terms (at least not in the context of C++
programming).

See the thread "convert hex to oct" where I gave a full example of how to
make a stream that interprets the comma as a space character, and thus you
can read "1,2,3" as stream >> x >> y >> z. It shows locales, facets, imbue.

Now I was playing around with the idea of locales and facets in order to see
how to use them. I have yet to use it in real code. Sometimes the locale
and facet thing seems overkill, and leads to obstruse semantics. On the
other hand, anything that's new seems this way at first, so I'm still trying
to keep an open mind to determine when and when not to use locales and
facets.

You can also learn about locales and facets in the later chapters of the
standard (which was my reference guide in writing the code), Stroustrup's
book. And I think PJ Plauger had lots of columns about these in a C++
magazine. If you can find those, they'd probably be the best reference.
 
J

Jerry Coffin

[ ... ]
I'm not sure what that sentence above means. What's a "facet"? And
what's a "locale"? And how do you "imbue" a stream with it? Sorry, but I
just don't recognize those terms (at least not in the context of C++
programming).

A locale describes how a set of characters in a character set should
be treated, interpreted, etc.

A locale consists of a number of facets -- each facet describes,
well...one facet of characters in that set. One facet describes the
basics of characters, such as which characters are considered letters,
digits, white-space, etc., in that character set. There are also
facets for how to read/write numbers, time values, how characters are
sorted, etc.

In your case, you want some custom processing done in reading numbers
from a stream. To do that, you start by creating a num_get facet,
which is object of a class derived (indirectly) from
std::locale::facet. It'll have to include some functions that take
input characters and convert them to numbers.

Using that is done in two steps. Each iostream has an associated
locale. Therefore, you have to 1) create a locale, and 2) tell the
istream to use that locale.

To create the locale, you usually specify a locale that uses the
facets from the default locale for everything except the thing(s) you
care about -- in this case, reading numbers. std::locale has a ctor
to do exactly that.

Having created a complete locale that uses your routines in its
num_get facet, you then have to tell the stream to use that locale --
this is done with a stream member function named imbue, so it's
generally called imbuing the stream with the locale.

This is a part of the library that many books completely or partly
skip over. There's a fair amount of "stuff" that you have to learn
before it all makes sense, and some of it perplexing even after you've
studied it (I'm pretty sure I still don't entirely understand codecvt
facets) but quite a bit of it is fairly easy to use once you learn
about it, and it really can make some tasks a lot easier than would
otherwise be the case. In particular, they allow you to modify
specific parts of how input or output is done in isolation. OTOH,
some (as Howard Hinnant hinted at) are difficult to get right -- he's
clearly a smart guy, and doesn't shrink away from doing some hard
programming when needed, so I (for one) wouldn't blithely ignore it
when he hints that someting is particularly difficult.
 
H

Howard

Thanks! That's very good information. I'd heard of locales before, but
didn't see how they applied to the OP's question at all. (I'd only seen
them used as a way to represent the characters of a particular language or
dialect, and hadn't ever looked into the details of using them.)

Thanks for the info...

-Howard (the other Howard)
 
T

tom_usenet

Thanks! That's very good information. I'd heard of locales before, but
didn't see how they applied to the OP's question at all. (I'd only seen
them used as a way to represent the characters of a particular language or
dialect, and hadn't ever looked into the details of using them.)

Thanks for the info...

There's lots about it here:
http://www.research.att.com/~bs/3rd_loc0.html

Tom
 

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,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top