views:

369

answers:

4

I'm on a custom C++ crash course. I've known the basics for many years, but I'm currently trying to refresh my memory and learn more. To that end, as my second task (after writing a stack class based on linked lists), I'm writing my own string class.

It's gone pretty smoothly until now; I want to overload operator>> that I can do stuff like cin >> my_string;. The problem is that I don't know how to read the istream properly (or perhaps the problem is that I don't know streams...). I tried a while (!stream.eof()) loop that .read()s 128 bytes at a time, but as one might expect, it stops only on EOF. I want it to read to a newline, like you get with cin >> to a std::string.

My string class has an alloc(size_t new_size) function that (re)allocates memory, and an append(const char *) function that does that part, but I obviously need to know the amount of memory to allocate before I can write to the buffer.

Any advice on how to implement this? I tried getting the istream length with seekg() and tellg(), to no avail (it returns -1), and as I said looping until EOF (doesn't stop reading at a newline) reading one chunk at a time.

A: 

you can use cin::getline( buffer*, buffer_size); then you will need to check for bad, eof and fail flags:

std::cin.bad(), std::cin.eof(), std::cin.fail()

unless bad or eof were set, fail flag being set usually indicates buffer overflow, so you should reallocate your buffer and continue reading into the new buffer after calling std::cin.clear()

catwalk
A: 

A side note: In the STL the operator>> of an istream is overloaded to provide this kind of functionality or (as for *char ) are global functions. Maybe it would be more wise to provide a custom overload instead of overloading the operator in your class.

pmr
A: 

Check Jerry Coffin's answer to this question.

The first method he used is very simple (just a helper class) and allow you to write your input in a std::vector<std::string> where each element of the vector represents a line of the original input.

That really makes things easy when it comes to processing afterwards!

Matthieu M.
+1  A: 

To read characters from the stream until the end of line use a loop.

char c;
while(istr.get(c) && c != '\n')
{
     // Apped 'c' to the end of your string.
}
// If you want to put the '\n' back onto the stream
// use istr.unget(c) here
// But I think its safe to say that dropping the '\n' is fine.

If you run out of room reallocate your buffer with a bigger size. Copy the data across and continue. No need to be fancy for a learning project.

Martin York
Thanks, I chose to do it this way. I need to work on my allocation routines now, though, because realloc() is called for every single byte a stream adds to the string. ;)