COPYING (not extracting) data from an istream object

Discussion in 'C++' started by Randy, Jan 16, 2006.

  1. Randy

    Randy Guest

    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
     
    Randy, Jan 16, 2006
    #1
    1. Advertising

  2. Randy

    Shark Guest

    >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?
     
    Shark, Jan 16, 2006
    #2
    1. Advertising

  3. Randy

    Randy Guest

    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
     
    Randy, Jan 16, 2006
    #3
  4. Randy

    Shark Guest

    >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?
     
    Shark, Jan 16, 2006
    #4
  5. Randy

    Randy Guest

    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
     
    Randy, Jan 16, 2006
    #5
  6. Randy wrote:
    > 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
     
    Victor Bazarov, Jan 16, 2006
    #6
  7. Randy

    Randy Yates Guest

    Victor Bazarov <> writes:

    > Randy wrote:
    >> 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'
    %%%% <> % *El Dorado*, Electric Light Orchestra
    http://home.earthlink.net/~yatescr
     
    Randy Yates, Jan 17, 2006
    #7
  8. Randy Yates wrote:
    > [...]
    > 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
     
    Victor Bazarov, Jan 17, 2006
    #8
  9. Randy

    Randy Yates Guest

    "Victor Bazarov" <> writes:

    > Randy Yates wrote:
    >> [...]
    >> 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)',
    %%%% <> % *A New World Record*, ELO
    http://home.earthlink.net/~yatescr
     
    Randy Yates, Jan 17, 2006
    #9
  10. Randy Yates wrote:
    > [..]
    > 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
     
    Victor Bazarov, Jan 17, 2006
    #10
  11. Randy Yates wrote:

    > 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.

    --
    Salu2
     
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Jan 17, 2006
    #11
  12. Randy

    Randy Guest

    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;
    }
     
    Randy, Jan 17, 2006
    #12
  13. Randy

    TB Guest

    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.

    --
    TB @ SWEDEN
     
    TB, Jan 17, 2006
    #13
  14. Randy

    thoth39 Guest

    > 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".

    --
    Pedro LamarĂ£o
     
    thoth39, Jan 17, 2006
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Victor Bazarov
    Replies:
    2
    Views:
    4,325
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=
    Nov 12, 2004
  2. =?ISO-8859-1?Q?Juan_Carlos_CORU=D1A?=

    How to return a IStream COM object?

    =?ISO-8859-1?Q?Juan_Carlos_CORU=D1A?=, Aug 7, 2003, in forum: Python
    Replies:
    0
    Views:
    2,322
    =?ISO-8859-1?Q?Juan_Carlos_CORU=D1A?=
    Aug 7, 2003
  3. Johannes Zellner

    extracting rest of an istream (istrstream)

    Johannes Zellner, Jan 20, 2006, in forum: C++
    Replies:
    4
    Views:
    427
    Mike Wahler
    Jan 20, 2006
  4. Replies:
    5
    Views:
    358
    Stuart Redmann
    May 10, 2006
  5. xmllmx
    Replies:
    5
    Views:
    597
    Jorgen Grahn
    Jun 15, 2010
Loading...

Share This Page