1

As an exercise, I'm trying to create a input stream manipulator that will suck up characters and put them in a string until it encounters a specific character or until it reaches eof. The idea came from Bruce Eckel's 'Thinking in c++' page 249.

Here's the code I have so far:

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

class siu 
{
    char T;
    string *S;
public:

    siu (string *s, char t)
    {
        T = t;
        S = s;
        *S = "";
    }


    friend istream& operator>>(istream& is, siu& SIU)
    {
        char N;
        bool done=false;
        while (!done)
        {
            is >> N;
            if ((N == SIU.T) || is.eof())
                done = true;
            else
                SIU.S->append(&N);
        }
        return is;
    }
};

and to test it....

        {
            istringstream iss("1 2 now is the time for all/");
            int a,b;
            string stuff, zork;

            iss >> a >> b >> siu(&stuff,'/');
            zork = stuff;
        }

the idea being that siu(&stuff,'/') will suck up characters from iss until it encounters the /. I can watch it with the debugger as it gets the characters 'n' 'o' 'w' through '/' and terminates the loop. It all seems to be going swimingly until I look at Stuff. Stuff has the characters now etc BUT there are 6 extra characters between each of them. Here's a sample:

  • &stuff 0x0012fba4 {0x008c1861 "nÌÌÌýoÌÌÌýwÌÌÌýiÌÌÌýsÌÌÌýtÌÌÌýhÌÌÌýeÌÌÌýtÌÌÌýiÌÌÌýmÌÌÌýeÌÌÌýfÌÌÌýoÌÌÌýrÌÌÌýaÌÌÌýlÌÌÌýlÌÌÌý"}

What's going on?

Offirmo
  • 18,962
  • 12
  • 76
  • 97
Mike D
  • 2,753
  • 8
  • 44
  • 77

1 Answers1

3

This line:

SIU.S->append(&N);

appends the character as a char *. The append function is expecting a null terminated string, so it keeps reading from &N, (&N)+1... until it sees a zero byte.

You can either make up a small null terminated char array and pass that in, or you can use the an alternate append function that takes a count and a character to append:

SIU.S->append(1, N);
The Dark
  • 134
  • 1
  • Thanks! So close but no cigar. I changed it to SIU.S->append(&N,1) and since I did want to include blanks, I replaced the is >> N; with N = is.get(). Seems to works as I hoped now. – Mike D Aug 27 '10 at 01:55
  • even simpler: while (is >> n) siu.s += n; Note: all-uppercase identifiers are - by convention - reserved for preprocessor defines... using them can lead to bugs that are very hard to track down. (though strangely, single letter ones ala template , U etc. is common pracice) – Tony Delroy Aug 27 '10 at 02:23
  • @Tony: Nothing that doesn't begin with an underscore is reserved by the language for anything. Any good style guide includes that rule, though. – Potatoswatter Aug 27 '10 at 05:54
  • Ok, this all gets me thinking about why either the iostream member function getline or the string member function getline can't be used in place of siu above. They have similar definition except for the operator business. Just thinking out loud. Seems like you need something like I did to define a temporary instance which you can't do with a function. Should be able to use either in the definition of siu operator >> though. – Mike D Aug 27 '10 at 12:08
  • @tony: S is a pointer to a string so I need *siu.S +=N; I wanted to stop at but not store the terminator so I changed the while to "while (!is.eof())" eliminated the done crud, and added a break when the terminator was encountered. – Mike D Aug 27 '10 at 12:21
  • It seems this would be a valuable tool for parsing input. One could embed any algorithm you wanted and even backup using put(). – Mike D Aug 27 '10 at 12:26