4

I want to know if it's possible to read a string of unknown size, until space or until newline is reached. What I did in c++ is this:

char * dynStr;
char buffer[20];

cin >> buffer;
dynStr = new char[strlen(buffer) +1];
strcpy(dynStr, buffer);

But the problem is, what if the entered input is bigger than 20? So I think it should be something like this:

do
{
 cin.get ( buffer, 20, ' '); //im not sure this is the right approach
 strcpy(.....); // if is not  a first iteration 
 //add the new buffer to the  end of dyn str..
} while( ! read ' ' or '\n' ) <--- this is what I have problem doing

I know in c++ I can use std::string , but I'd like to know how to do this thing, so if you have any ideas, tell me :)

melpomene
  • 84,125
  • 8
  • 85
  • 148
Petar D.
  • 149
  • 1
  • 5
  • 15
  • 6
    Not only *can* you use `std::string` in C++, but you *should* use it for modern, "natural" C++. – crashmstr Nov 04 '16 at 12:47
  • Whatever you try, *don't* attempt to read single chars to assemble the string. Because: Both kinds of delete keys (and to add something to this problem, line breaks in the console if the line is too long), arrow keys, and many other problems. – deviantfan Nov 04 '16 at 12:49
  • If you don't want to use `std::string`, you can read characters one by one into `std::deque` or `std::vector` or whatever. – HolyBlackCat Nov 04 '16 at 12:49
  • @HolyBlackCat (rolleyes) If you have a solution for the mentioned problems without rewriting the OS console or writing about ten thousand ncurses lines, please, it would be very interesting – deviantfan Nov 04 '16 at 12:50
  • @deviantfan When I posted that your comment hasn't yet loaded for me. But where is the problem? Can't one just filter out non-printable chars? – HolyBlackCat Nov 04 '16 at 12:52
  • @HolyBlackCat `Can't one just filter out non-printable chars?` And then? How does this allow the user to move around in the string with arrow keys before pressing enter? etc. – deviantfan Nov 04 '16 at 12:54
  • 4
    @deviantfan I don't understand what you mean. If I understand correctly, OP just wants to reimplement `cin >> std::string` without the `std::string`. – HolyBlackCat Nov 04 '16 at 12:56
  • @HolyBlackCat Yes, and my comment meant that "using some function to detect single key presses" is not a viable solution. – deviantfan Nov 04 '16 at 12:58
  • 1
    @deviantfan Your comment was about reading chars, not detecting key presses. Keys aren't chars. – melpomene Nov 04 '16 at 12:59
  • 2
    @melpomene Right, but if someone would read the full comment... this whole discussion has no purpose. ... This is one of the questions where some people don't like someone don't want to use std::string, so they start nitpicking on everyone not recommending std::string... typical SO. – deviantfan Nov 04 '16 at 13:02
  • @HolyBlackCat yes, thats exactly what I want – Petar D. Nov 04 '16 at 13:02
  • @deviantfan If you're not going with the `std::string` approach, what else is there to do but read characters one by one and assemble them? Your comments read like you're notpicking on everyone not recommending std::string. – melpomene Nov 04 '16 at 13:04
  • @melpomene Exactly who was a nitpick-target of me because he/she does not use std::string here? ... Again about my first comment, see eg. the getch function family. It takes a key press and returns a char (char-type value, not a Unicode character/glyph/whatever). That was what I was talking about. – deviantfan Nov 04 '16 at 13:07
  • @deviantfan HolyBlackCat. – melpomene Nov 04 '16 at 13:11
  • (Apparently my previous comment was too offensive to be kept, so again: Please read full comments. I do *not* believe that std::string is the only good solution) – deviantfan Nov 04 '16 at 13:37

1 Answers1

2

get() and several other methods, can only read until a single specific character has been read. You want to read until either a newline or a space is received.

For a simple situation like that, it is better to simply use

cin.get();

to read one character at a time, appending it to your string, checking each character for a space or a newline is read. Depending on your specific situation you might need to use peek(); also.

This may not be very efficient, but for a simple excersize in reading from a stream this would be a good starting point. After you get that working, you could then read the documentation for the read() method, and implement a more sophisticated algorithm for reading and buffering larger chunks of text, from the stream, and then manually searching each read buffer for the next space or newline, and if found save the remaining text in the buffer to be processed later.

Start with a simple initial logic that reads one character at a time, and then progress to a more sophisticated approach.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • That sounds good, can you tell me if reading the input 1 by 1 character with cin.get() is slower then taking a whole word with cin >>? – Petar D. Nov 04 '16 at 13:05
  • @user7091569 This is what many implementations do for `cin>>s`. See for instance http://www.sgi.com/tech/stl/string search/find `operator>>`. – Captain Giraffe Nov 04 '16 at 14:16
  • @user7091569: Why don't you just measure it? Can *you* find a difference in speed? – Christian Hackl Nov 04 '16 at 15:33