COPYING (not extracting) data from an istream object

R

Randy

Is there any way to do this? I've tried tellg() followed by seekg(),
inserting the stream buffer to an ostringstream (ala os << is.rdbuf()),
read(), and having no luck.

The problem is, all of these methods EXTRACT the data at one
point or another. The other problem is there appears to be NO
WAY to get at the actual buffer pointer (char*) of the characters
in the stream. There is a way to get the streambuf object
associated with the stream (rdbuf()), but the gptr() member
function of the streambuf object is protected.

Help!!!

--Randy Yates
 
S

Shark

The problem is, all of these methods EXTRACT the data at one
point or another. The other problem is there appears to be NO
WAY to get at the actual buffer pointer (char*) of the characters
in the stream. There is a way to get the streambuf object
associated with the stream (rdbuf()), but the gptr() member
function of the streambuf object is protected.

How many streams can you have at one time? If I open a file ifstream
fin1("blah.txt") and ifstream fin2("blah.txt"), then are fin1 and fin2
copies of each other or are they both referencing the same stream?

Another question comes to mind: you took an output stream, and copied
it. If you flush both streams, lets say at one time in a (OT) thread
(/OT) is the behavior defined somewhere?
 
R

Randy

Shark,

I don't understand the point of your first question, and I don't
understand your second question at all. The answer to the
first question is "one." I will only have one stream open at a
time in this context.

--Randy
 
S

Shark

I don't understand the point of your first question, and I don't
understand your second question at all. The answer to the
first question is "one." I will only have one stream open at a
time in this context.

oh sorry about that, my question was to a broad "you audience" of which
"you" and "me" are subsets :)

Basically how many streams can we have at one time, and are these like
little tributaries to a river? std out, ofstream derive from ostream
etc. but in the end are these streams combined or they all go different
ways?

Suppose standard output stream can be copied and various copies exist.
If we flush each of them using endl, will we observe a defined
behavior?
 
R

Randy

I have one and only one question: How do you COPY N characters in
an input stream into a char buffer[N] array? I'd appreciate an answer
to that question.

--RY
 
V

Victor Bazarov

Randy said:
I have one and only one question: How do you COPY N characters in
an input stream into a char buffer[N] array? I'd appreciate an answer
to that question.

Have you tried implementing it yourself? I'd look into 'sgetn' and all
the positioning functions for the stream buffer... The idea is to first
preserve the position of the buffer by calling

pos_type pos = os.pubseekoff(0, ...); // look up the other arguments

then

int got = os.sgetn(where, N);

and then restore the position

os.pubseekpos(pos, ..

Of course you can run into a streambuf implementation that can't really
set its position, but for files it should work fine.

V
 
R

Randy Yates

Victor Bazarov said:
Randy said:
I have one and only one question: How do you COPY N characters in
an input stream into a char buffer[N] array? I'd appreciate an answer
to that question.

Have you tried implementing it yourself?

Yes, albeit not very hard. I guess I'm waffling between doing that and
thinking there must be a better way.

As I said, I also can't see a way to get at the actual character
pointer that must be buried somewhere. I suppose I could create a
class that derives from streambuf() and then expose the

Has NO one EVER wanted to "peek" (at more than one character at a
time) into an extractor stream???? I'm amazed the istream class
doesn't provide this function "out-of-the-box."

I mentioned in another post *why* I'm trying to do this:

I'm creating a set of classes for some functions that require
lots of parameters. A simple, human-readable and -controllable
way to do this is to overload the inserter and extractor
operators to report and control these parameters as
property/value pairs, e.g., "ParameterA=value1".

The idea is to feed a list of property/value pairs to the top-level
class, have his extractor interpret and set the properties that
pertain to it (and ignore those that don't), then pass the entire set
to the child classes, the children to their grandchildren, etc.
(speaking hierarchically and/or inheritance-wise).

So, I need to operate on an istream without wasting the
string (or stream) in it.

Is this so unusual? Am I mis-using the extractor class or abusing the
operators somehow by wanting to do this?
I'd look into 'sgetn' and all
the positioning functions for the stream buffer... The idea is to first
preserve the position of the buffer by calling

pos_type pos = os.pubseekoff(0, ...); // look up the other arguments

then

int got = os.sgetn(where, N);

and then restore the position

os.pubseekpos(pos, ..

Of course you can run into a streambuf implementation that can't really
set its position, but for files it should work fine.

That's just it - these aren't necessarily file streams, and I've found,
at least within the istream class, that tellg() and seekg() don't work
with non-file streams. I'm thinking these gets and seeks won't either.
--
% Randy Yates % "Midnight, on the water...
%% Fuquay-Varina, NC % I saw... the ocean's daughter."
%%% 919-577-9882 % 'Can't Get It Out Of My Head'
%%%% <[email protected]> % *El Dorado*, Electric Light Orchestra
http://home.earthlink.net/~yatescr
 
V

Victor Bazarov

Randy said:
[...]
Has NO one EVER wanted to "peek" (at more than one character at a
time) into an extractor stream???? I'm amazed the istream class
doesn't provide this function "out-of-the-box."

What's the point? Extract all available characters into a string-
based stream and peek (peer) as much as you need.

Character-based streams only have characters. And either they are
empty, or you can extract one and work on it. If your streams are
not file-based, extracting a single character can probably trigger
extraction of the next one. How would you peek at others?

Can you describe why you'd need to peek at more than one and what
is the reason extracting all available chars into a separate buffer
and working with it doesn't solve your problem?

V
 
R

Randy Yates

Victor Bazarov said:
Randy said:
[...]
Has NO one EVER wanted to "peek" (at more than one character at a
time) into an extractor stream???? I'm amazed the istream class
doesn't provide this function "out-of-the-box."

What's the point? Extract all available characters into a string-
based stream and peek (peer) as much as you need.

Character-based streams only have characters. And either they are
empty, or you can extract one and work on it. If your streams are
not file-based, extracting a single character can probably trigger
extraction of the next one. How would you peek at others?

Can you describe why you'd need to peek at more than one and what
is the reason extracting all available chars into a separate buffer
and working with it doesn't solve your problem?

Yes.

I need to peek at more than one character at a time because I'm trying
to match a string of the form "propertyX=valueY." I need to peek rather
than extract the characters because, if any one overloaded extractor
doesn't match the property/value pair being passed, the string should
stay "in the stream" for searching by other class instances (other
class member elements within a class).

It's like this. I've got a set of enumeration classes that are derived
from a CENUM(propertyName, comma-delimited-property-value-list) class that
defines a set of property/value pairs. Any one class, say, classA, may contain
several of these enumeration classes as member elements. For example,

class Cars : CENUM
{
CENUM("CARS", "Mustang, Pinto, Maverick"); /* am I showing my age? */
}

class Trucks : CENUM
{
CENUM("TRUCKS", "Mack, International");
}

class Vehicles
{
Cars cars;
Trucks trucks;
AnotherClass ac;
friend istream& operator>> (istream& is, Vehicles& vehicles);
}

I want to be able to "parse" a set of property/value pairs coming down
an istream like this:

istream& operator>> (istream& is, Vehicles& vehicles)
{
is >> vehicles.cars;
is >> vehicles.trucks;
is >> vehicles.ac;

return is;
}

So if I wanted to set the trucks parameter to "International", I
can simply stream the string "TRUCKS=International" into the
vehicles class.

I can't extract all available chars in any one overloaded extractor
because if the property/value pair doesn't match, I want it to
remain in the stream for passing to subsequent classes.

Does that help explain the predicament?
--
% Randy Yates % "Watching all the days go by...
%% Fuquay-Varina, NC % Who are you and who am I?"
%%% 919-577-9882 % 'Mission (A World Record)',
%%%% <[email protected]> % *A New World Record*, ELO
http://home.earthlink.net/~yatescr
 
V

Victor Bazarov

Randy said:
[..]
I can't extract all available chars in any one overloaded extractor
because if the property/value pair doesn't match, I want it to
remain in the stream for passing to subsequent classes.

Does that help explain the predicament?

It's not a predicament. It's a bad design and misuse of streams.
Extract as much as you can into a separate buffer and make your
"overloaded extractor" and "subsequent classes" work with that buffer
instead of streams. Problem solved.

V
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Randy said:
I can't extract all available chars in any one overloaded extractor
because if the property/value pair doesn't match, I want it to
remain in the stream for passing to subsequent classes.
Does that help explain the predicament?

No. If you need a function, class, or whatever that does something you can
write it. Demanding his inclusion in the standard library and waiting for
compilers to implement it takes too much or infinite time.
 
R

Randy

It may be a misuse of streams, but it damn sure is handy.

Here's the solution:

void peekline(istream& is, string& strLine)
{
char line[CEnum::TOKEN_MAX_CHARS];
int ch;
uint16_t n;
uint16_t m;

ch = 1;
for (n = 0; (n < CEnum::TOKEN_MAX_CHARS) && (ch != -1); n++)
{
ch = is.rdbuf()->sbumpc();
line[n] = *((char*)&ch + 0);
}

for (m = 0; m < n; m++)
{
is.rdbuf()->sungetc();
}

line[n-1] = 0;
strLine = line;
}
 
T

TB

Randy sade:
It may be a misuse of streams, but it damn sure is handy.

Here's the solution:

void peekline(istream& is, string& strLine)
{
char line[CEnum::TOKEN_MAX_CHARS];
int ch;
uint16_t n;
uint16_t m;

ch = 1;
for (n = 0; (n < CEnum::TOKEN_MAX_CHARS) && (ch != -1); n++)
{
ch = is.rdbuf()->sbumpc();

And if sbumpc() returns traits::eof()?
line[n] = *((char*)&ch + 0);
}

for (m = 0; m < n; m++)
{
is.rdbuf()->sungetc();

Same here.
 
T

thoth39

Has NO one EVER wanted to "peek" (at more than one character at a
time) into an extractor stream???? I'm amazed the istream class
doesn't provide this function "out-of-the-box."

You seem to want a stream to behave like an array of bytes.
If you want an array of bytes, read from the stream and write to an
array of bytes.

A stream is not necessarily something you can peek into. If this stream
wraps over a network connection, after bytes are read from the
operating system's buffers, they are effectively "lost".
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top