0

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.

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
exscape
  • 2,185
  • 4
  • 21
  • 25

4 Answers4

1

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
  • 257,169
  • 86
  • 333
  • 562
  • 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. ;) – exscape Nov 06 '09 at 12:40
0

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
  • 6,340
  • 25
  • 16
0

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
  • 58,701
  • 10
  • 113
  • 156
0

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!

Community
  • 1
  • 1
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722