Can't read in a long cin input to a string - c++

I have code that looks like this
string inputString;
std::getline (std::cin, inputString)
cout << inputString;
when I cin a long string ~30k characters then inputString only has part of that string. Any ideas how to fix this?

From the std::getline() documentation on cppreference.com:
getline reads characters from an input stream and places them into a string:
1. Behaves as UnformattedInputFunction, except that input.gcount() is not affected. After constructing and checking the sentry object, performs the following:
Calls str.erase()
Extracts characters from input and appends them to str until one of the following occurs (checked in the order listed)
a. end-of-file condition on input, in which case, getline sets eofbit.
b. the next available input character is delim, as tested by Traits::eq(c, delim), in which case the delimiter character is extracted from input, but is not appended to str.
c. str.max_size() characters have been stored, in which case getline sets failbit and returns.
If no characters were extracted for whatever reason (not even the discarded delimiter), getline sets failbit and returns.
2. Same as getline(input, str, input.widen('\n')), that is, the default delimiter is the endline character.
So check to see if your input is being limited by the value of inputString.max_size(). It might be near 32k on your system.

By default, the terminal works in canonical mode, and it has a buffer of the length 4096 Bytes. So that's why the maximum input that the string can take is 4095. Now the solution is to change to the noncanonical mode in Linux. You can do so by
$ stty -icanon # for switching to the noncanonical mode.
$ stty icanon # reverting back to the canonical mode when you are done.

Related

How to promt the user correctly? [duplicate]

Here is the code:
string str;
cin>>str;
cout<<"first input:"<<str<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;
The result is that getline never pauses for user input, therefore the second output is always empty.
After spending some time on it, I realized after the first call "cin>>str", it seems '\n' is still stored in cin (using cin.peek() to check), which ends getline immediately. The solution will be adding one more line between the first usage and the second one:
cin.ignore(numeric_limits::max(), '\n');
However, I still don't understand, why is '\n' left there after the first call? What does istream& operator>> really do?
The \n is left in the input stream as per the way operator>> is defined for std::string. The std::string is filled with characters from the input stream until a whitespace character is found (in this case \n), at which point the filling stops and the whitespace is now the next character in the input stream.
You can also remove the \n by calling cin.get() immediately after cin>>str. There are many, many different ways of skinning this particular I/O cat, however. (Perhaps a good question in and of itself?)
By default, the stream insertion operator reads until it sees whitespace. Your first call isn't returning until it sees a space, tab, newline, etc. Then the next character needs to be consumed so that you can get to the next one.
I generally recommend only doing line-oriented input from std::cin. So, your code could look something like this:
string str;
int val;
// Read an entire line and parse an integer from it
{
string line;
getline(cin, line);
istringstream iss(line);
iss >> val;
}
cout<<"first input:"<<val<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;
Be sure to add error checking too.
The getline-only approach avoids having to think about line buffering of the input, of clearing the input, etc. If you directly read something with >>, the input does not terminate if the user hits enter instead of inputting what is required, but instead continues until a token is input (this behavior is usually not wanted).
As others have said, th problem is that the newline is left from the first extraction. One solution I do is to discard all the left characters in the stream:
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
Good writeup that explains some of the reasons why you are running into this issue, primarily due to the behavior of the input types and that you are mixing them
Also was searching for most suitable solution. Implementation of this operator could produce problems. And not always is acceptable to read entire line, or not mix different types in one input line.
To solve problem, when you want to read some data from cin, and don't know if whitespaces was correctly extracted after last input operation, you can do like this:
std::string str;
std::cin >> std::ws >> str;
But you can't use this to clear trailing newline symbol after last input operation from cin to do not affect new input, because std::ws will consume all whitespaces and will not return control until first non-ws character or EOF will be found, so pressing enter will not finish input process.
In this case should be used
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
which is more flexible.
P.S. If got errors with max() function such as "identifier expected", it could be caused by max macros defined in some header (for example, by Microsoft); this could be fixed by using
#undef max

why does cin works wheras cin.getline doesn't?

My code is
char buffer[10]={0};
cin>>buffer; //here i enter the contents as "12345678912345"
//Now i tried to enter 14 characters into a buffer of 10
cin>>buffer; //This works as it waits for input on the console
cout<<buffer;
wheras
char buffer[10]={0};
cin>>buffer;//same input as above "12345678912345"
cin.getline(buffer,10);//This doesn't wait for input on console and returns
cout<<buffer;
why does this happen?
THANKS:
thanks everyone for your answers they were helpful
Neither of your code-snippets "work" in the sense that both overflow the buffer in the first input line. This is not a good thing at all.
The second case doesn't wait for input because of technical differences between operator>> and getline - they react differently to the newline character that you have entered. When reading the first cin >> buffer, the newline at the end of the input is left in the input stream (cin). In your first case, the second cin >> buffer will skip over the newline that is in the input buffer, and then wait for more input.
In the second case, because of the workings of getline, it accepts the remaining newline as input, and buffer is not filled in with anything.
This is a common problem when mixing getline and operator>> for input. The best solution to solve that particular problem is to either use only operator >> or only getline - there are various other solutions, but they are generally quite tricky to get just right.
First off you have a buffer overrun: Reading to a char* stops when the stream goes bad, a space is found, or the width() is exhausted if it were bigger than 0. You want to use
std::cin >> std::setw(10) >> buffer;
Assuming this undefined behavior is abouded, the difference between using formatted and unformatted input for the second read is that formatted input starts with skipping leading whitespace whike unformatted input does not. Your first input stopped right before the newline character resulting from the enter key. That newline is good enough for getline() but it is skipped when using >>.
When switching between formatted and unformatted I/O you normally want to skip leading whitespace using, e.g., the std::ws manipulator:
(std::cin >> std::ws). getline(buffer, 10);
You should also consider using std::string together with std::getline().
When you input the value for buffer in console, the return is still stored in the input stream.
Hence the termination character '\n' is already read by getline() from the previous read operation. This is why this function does not wait further for user input.
Try reading the getline() before the cin >> operation.
Also, as noted by Mike, you should be careful not to cause buffer overflow.
The >> operator does not consume any whitespace including the newline. The getline function returns when it sees a newline. Your problem is the newline that >> statement leaves at the buffer. You can solve this by consuming all characters, including the newline until you see a newline in the buffer. See the ignore function:
char buffer[10]={0};
cin>>buffer;
cin.ignore('\n', 256);
cin.getline(buffer,9);
cout<<buffer;
return 0;

Possible to discard return character when using std::cin >>?

When using the >> operator in c++ to capture user input, is it possible to prevent the console from printing the newline that is generated when the user presses the return key?
You cannot prevent newline character, because when you use cin, you are communicating with system core, which is not under control by users. console will return, when you enter \n or EOF or other exception situation.
So the better way is to use getchar() to capture the '\n', and do not leave it in buffer.
It is possible to prevent this newline behavior by inputting two EOFs instead of Carriage Return from the keyboard. After entering your string at the console prompt, hit
CTRL-D, CTRL-D
Note, this is a platform specific answer. This works on my Mac, but on Windows OS the EOF sequence may be CTRL-Z, RETURN. I would appreciate an answer edit <-- HERE.
Alternately, you can ditch the >> operator and use something like std::getline and specify an exact string termination delimiter. For example:
std::string myString;
std::getline(std::cin, myString, ';');
std::cout << myString;
This will read from standard input to myString, and put the string terminating NULL character where it finds the first semicolon ';'. Then you'll only have to hit CTRL-D (input EOF) once.
You can enter the values or input by pressing space every time. But at the end you must press enter key.
Let's say: you want to enter "5,4,3,2,1"
You can do: 5 [enter] 4 [enter] 3[enter] 2[enter] 1[enter]
Also: 5[space]4[space]3[space]2[space]1[enter]
But if you want to print the output near input, you can simply print the input first and than you can print the what you want.
Example:
Input: 3 Output: input+1
So you will do:
cout<<input;
cout<<" "<<input+1<<endl;
Good luck :)

C++ cin fails when reading more than 127 ASCII values

I've created a text file that has 256 characters, the first character of the text file being ASCII value 0 and the last character of the text value being ASCII value 255. The characters in between increment from 0 to 255 evenly. So character #27 is ASCII value 27. Character #148 should be ASCII value 148.
My goal is to read every character of this text file.
I've tried reading this with cin. I tried cin.get() and cin.read(), both of which are supposed to read unformatted input. But both fail when reading the 26th character. I think when I used an unsigned char, cin said it was reading read in 255, which simply isn't true. And when I used a normal signed char, cin said it was reading in -1. It should be reading in whatever the character equivalent of ASCII 26 is. Perhaps cin thinks it's hit EOF? But I've read on separate StackOverflow posts previously that EOF isn't an actual character that one can write. So I'm lost as to why cin is coughing on character values that represent integer -1 or integer 255. Could someone please tell me what I'm doing wrong, why, and what the best solution is, and why?
There's not much concrete code to paste. I've tried a few different non-working combinations all involving either cin.get() or cin.read() with either char or unsigned char and call casts to char and int in between. I've had no luck with being able to read past the 26th character, except for this:
unsigned char character;
while ( (character = (unsigned char)cin.get()) != EOF) { ... }
Interestingly enough though, although this doesn't stop my while loop at the 26th character, it doesn't move on either. It seems like cin, whether its cin.get() or cin.read() just refuses to advance to the next character the moment it detects something it doesn't like. I'm also aware that something like cin.ignore() exists, but my input isn't predictable; that is, these 256 characters for my text file are just a test case, and the real input is rather random. This is part of a larger homework assignment, but this specific question is not related to the assignment; I"m just stuck on part of the process.
Note: I am reading from the standard input stream, not a specific text file. Still no straightforward solution it seems. I can't believe this hasn't been done on cin before.
Update:
On Windows, it stops after character 26 probably due to that Ctrl-Z thing. I don't care that much for this problem. It only needs to work on Linux.
On Linux, though, it reads all characters from 0 - 127. But it doesn't seem to be reading the extended ASCII characters from 127 to 255. There's a "solution" program that produces output we're supposed to imitate, and that program is able to read all 255 characters somehow.
Question: How, using cin, can I read all 255 ASCII characters?
Solved
Using:
int characterInt;
unsigned char character;
while ( (characterInt = getchar()) != EOF )
{
// 'character' now stores values from 0 - 255
character = (unsigned char)(characterInt);
}
I presume you are on windows. On the windows platform character 26 is ctrl-z which is used in a console to represent end of file, so the iostreams is thinking your file ends at that character.
It onlt does this in text mode which cin is using, if you open a steam in binary mode it won't do this.
std::cin reads text streams, not arbitrary binary data.
As to why the 26th character is interesting, you are probably using a CP/M derivative (such as MS-DOS or MS-Windows). In those operating systems, Control-Z is used as an EOF character in text files.
EDIT:
On Linux, using g++ 4.4.3, the following program behaves precisely as expected, printing the numbers 0 thru 255, inclusive:
#include <iostream>
#include <iomanip>
int main () {
int ch;
while( (ch=std::cin.get()) != std::istream::traits_type::eof() )
std::cout << ch << " ";
std::cout << "\n";
}
There are two problems here. The first is that in Windows the default mode for cin is text and not binary, resulting in certain characters being interpreted instead of being input into the program. In particular the 26th character, Ctrl-Z, is being interpreted as end-of-file due to backwards compatibility taken to an extreme.
The other problem is due to the way cin >> works - it skips whitespace. This includes space obviously, but also tab, newline, etc. To read every character from cin you need to use cin.get() or cin.read().

Actual difference between end of line and end of file under windows?

I understand EOF and EOL but when I was reading this question (second part of answer) and i got my concepts broken :
Specially the para :
It won't stop taking input until it finds the end of file(cin uses
stdin, which is treated very much like a file)
so i want to know when we do some thing like in c++ under windows :
std::cin>>int_var; , and we press enter , this end the input but according to reference link it should only stop taking input after hitting ctrl+z.
So i would love to know how std::*stream deal with EOF and EOL.
Second part:
please have a look at this example :
std::cin.getline(char_array_of_size_256 ,256);
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "artist is " << artist << endl;
If i remove std::cin.ignore() it simply stops taking input (which is known case) but when i keep it , it waits for a new input which is ended by '\n' . But it should simply clear up stream rather then waiting for any new input ending-up with '\n'.
Thanks for giving you time)
End-of-line and end-of-file are very different concepts.
End-of-line is really just another input character (or character sequence) that can appear anywhere in an input stream. If you're reading input one character at a time from a text stream, end-of-line simply means that you'll see a new-line ('\n') character. Some input routines treat this character specially; for example, it tells getline to stop reading. (Other routines treat ' ' specially; there's no fundamental difference.)
Different operating systems use different conventions for marking the end of a line. On Linux and other Unix-like systems, the end of a line in a file is marked with a single ASCII linefeed (LF, '\n') character. When reading from a keyboard, both LF and CR are typically mapped to '\n' (try typing either Enter, Control-J, or Control-M). On Windows, the end of a line in a file is marked with a CR-LF pair (\r\n). The C and C++ I/O systems (or the lower-level software they operate on top of) map all these markers to a single '\n' character, so your program doesn't have to worry about all the possible variations.
End-of-file is not a character, it's a condition that says there are no more characters available to be read. Different things can trigger this condition. When you're reading from a disk file, it's just the physical end of the file. When you're reading from a keyboard on Windows, control-Z denotes end-of-file; on Unix/Linux, it's typically control-D (though it can be configured differently).
(You'll usually have an end-of-line (character sequence) just before end-of-file, but not always; input can sometimes end in an unterminated line, on some systems.)
Different input routines have different ways of indicating that they've seen an end-of-file condition. Read the documentation for each one for the details.
As for EOF, that's a macro defined in <stdio.h> or <cstdio>. It expands to a negative integer constant (typically -1) that's returned by some functions to indicate that they've reached an end-of-file condition.
EDIT: For example, suppose you're reading from a text file containing two lines:
one
two
Let's say you're using C's getchar(), getc(), or fgetc() function to read one character at a time. The values returned on successive calls will be:
'o', 'n', 'e', '\n', 't', 'w', 'o', '\n', EOF
Or, in numeric form (on a typical system):
111, 110, 101, 10, 116, 119, 111, 10, -1
Each '\n', or 10 (0x0a) is a new-line character read from the file. The final -1 is the value of EOF; this isn't a character, but an indication that there are no more characters to be read.
Higher-level input routines, like C's fgets() and C++'s std::cin >> s or std::getline(std::cin, s), are built on top of this mechanism.
First "part"
so i want to know when we do some thing like in c++ under windows : std::cin>>int_var; , and we press enter , this end the input but according to reference link it should only stop taking input after hitting ctrl+z.
No, you're confusing formatted input operations with stream iterators. The following will use the formatted input operation (operator>>) repeatedly until the end of file is reached because the "end iterator" represents the end of the stream.
std::vector<int> integers;
std::copy(
std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(integers));
If you use the following:
int i = 0;
std::cin >> i;
in an interactive shell (e.g. in console mode), std::cin will block on user input which is acquired line by line. So, if no data (or only white space) is available, this operation will actually force the user to type a line of input and press the enter key.
However,
int i = 0;
int j = 0;
std::cin >> i >> j;
may block on one or two lines of input, depending on what the user types. In particular, if the user types
1<space>2<enter>
then the two input operations will be applies using the same line of input.
Second "part"
Considering the code snippet:
std::cin.getline(char_array_of_size_256 ,256);
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "artist is " << artist << endl;
If the line contains 255 or less lines of character data, std::cin.getline() will consume the end-of-line character. Thus, the second line will consume all characters until the next line is completed. If you want to capture only the current line and ignore all characters past 256, I suggest you use something like:
std::cin.getline(char_array_of_size_256 ,256);
if (std::cin.gcount() == 256) {
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cout << "artist is " << artist << endl;
On the second part:
When the linked answer said "read into a string", I guess they meant
std::string s;
std::getline(std::cin, s);
which always reads the entire line into the string s (while setting s to the proper size).
That way there is nothing left over from the input line to clean up.