scanf(%s) an issue with EOF - c++

Im using scanf because we must use it.
the problem is the following :
(thats just an example of the problem):
int main() {
char ch [10]={0};
scanf("%s",ch);
printf("%s",ch);
}
if i run the program and enter for example : word^Z
when ^Z is EOF.
the program stays in place, stuck in the scanf, althogh i did type word then ctrl+z then Enter. but somehow it stays in the scanf, its the same thing with redirection, like its not a problem with ctr+z or anything.
i hope that i can get some help
thanks in advance,
totally apprecaite it :)

scanf uses whitespace as a delimiter to store the read data into various fields. From the command line, entering ControlZ, then Enter only puts the EOF character into the input stream and scanf() continues waiting for whitespace. If you hit Enter again, scanf will receive the whitespace character, and everything including the EOF will be stored into the ch array.
Here's a sample run. The first line is the input, and the second line is the output.
Hello^Z
Hello→

Related

in c++ program after pressing enter , "cin" will feed all Variables

I have a program that takes two numbers and shows them on the screen.
However, when I hit "enter" after I input the first number, my program shows the answers before letting me input the second number.
Why does this happen?
int main()
{
int n1;
float n2;
cin>>n1;
cin>>n2;
cout<<"int n:"<<n1<<endl<<"float n:"<<n2;
return 0;
}
I wanna input 0.25 and 35 but when I write 0.25 and hit enter suddenly shows the answer "int: n:0 float n:0.25" it doesn't let me write second num. my os is Win10 and this program compiled with DevCpp
It works when both variables are ints.
There is no difference between cin>>n1; cin>>n2; and cin >> n1 >>n2. Enter key only serves as signal to sychronize input buffer and stream buffer. cin doesn't input per line, it parses buffer when there is available volume of data. If parse incomplete, it waits. If parse can't be done, it stops and state bit changes. To continue parsing you have either ignore or clear part or whole buffer content.
Something wrong was entered in first line, causing cin to go into bad() state. Edge case might happen if you're running program through a remote terminal, some incorrect character could slip in, e.g. ^M generated by new line from Windows would break cin stream on Linux. That's also case if you input from a file which was saved on different platform. On Windows line ends consist of two characters, #10 and #13. On linux steams expect only #13 as a new line and buffer flush signal, #10 is an unexpected character.
Edit (after OP gave information about input data):
"0.25" would be parsed as "0" and ".25", that expected and documented stream behavior. Parsing for n1 had stopped as soon as stream encountered character which doesn't fit int pattern, which could be space, end of line, alphabetic or punctuation. Period considered a punctuation in this case
Then it tries to get a float from stream input and buffer contains ".25". It's a legal float notation and it gets assigned to n2.
When you have both "int", you cannot get second value at all with same input, it always will be 0, because cin locks up in bad state, i.e. method its istream::good() returns false. You have to check state of stream after reading variables. Any further formatted reading that wouldn't be able to parse .25 wouldn't advance stream past that point.
If you want to read from stream exclusively line by line, you have to use istream::getline() method to get the string. There is also method get which can acquire content of stream and ignore which allows to discard part of stream.

C++ multiple cin.get()

Could seem an old question, but the problem here isn't the use of TWO cin.get(), but of more than two! if I write (in DEV C++)
I get just one input request (s) and then end program. Now, I expected having at least two request of cin, because I expected:
char s[50];
char t[100];
char r[100];
char f[100];
cin.get(s,49);
cin.get(t,99);
cin.get(r,99);
cin.get(f,99);
I expeted at least 2 input request, because:
first cin: buffer empty,I insert the string s and \n
second cin: I have in buffer \n still, then t=\n without input request
third cin: buffer empty, I insert the string r and \n
fourth cin: I have in buffer \n still, then f=\n without input request
But I have just the input request for s string!
why have I just one input request?the buffer didn't clean with second cin.get, letting third cin.get work properly? Thanks
t does NOT equal '\n'. It's empty. .get(char*,int) will never remove the '\n' from the buffer.
Worse, the attempt to read to t will set cin to a fail state since nothing could be read, which will cause all subsequent reads of any sort from cin to fail immediately without even trying until you .clear() the fail state.
This is surprising behavior, but you seem to have already guessed at most of it as per your last sentence in the question, so, Good Job! You're learning!
http://en.cppreference.com/w/cpp/io/basic_istream/get

Why do I have to press enter Twice?

For some reason in my program when I reach a certain spot, I have to press Enter twice in order to get it to submit. I added the clear to keep it from skipping input and the ignore() to keep it from keeping any extra characters in the buffer. I enter my input and then it drops down to a new line, I hit Enter again and it enter the input and continues the program no problem but I'm wondering why. Here's a code snippet:
cin.ignore();
cout << "Enter Student Major (ex. COSC): ";
cin.getline(student.major, 6);
for(int i = 0; i < sizeof(student.major); i++)
student.major[i] = toupper(student.major[i]);
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Any suggestions?
It seems to me that you are tossing too many cin.ignore() around, not knowing exactly why they are needed and when to put them there.
There are two common circumstances where cin.ignore() is needed to "make input work right":
when mixing formatted and unformatted input;
to recover from a formatted input error.
In both cases, you want to get rid of spurious characters from the input buffer; if there isn't any such character (which is probably what happens in your program), cin.ignore() will pause the execution and wait for user input - after all, you asked it to ignore some characters, and dammit, it will obey to its orders.
(although ignore() by default would "eat" just one character, whatever it may be, the execution is paused until a newline is found because by default cin is line buffered - new input is not examined until a newline is recieved)
Case 1:
cin.ignore() calls are often needed if you are performing an unformatted input operation (like getline) after performing a formatted input operation (i.e. using the >> operator).
This happens because the >> operator leaves the newline in the input buffer; that's not a problem if you are performing only formatted input operations (by default they skip all the whitespace before trying to interpret the input), but it's a problem if afterwards you do unformatted input: getline by default reads until it finds a newline, so the "spurious newline" left will make it stop reading immediately.
So, here you will usually call cin.ignore(...) call to get rid of the newline just after the last formatted input operation you do in a row, guaranteeing that the input buffer is empty. Afterwards, you can call getline directly without fear, knowing that you left the buffer empty.
It's a bad idea, instead, to put it before any getline, as you seem to do in your code, since there may be code paths that lead to that getline that have the input buffer clean, so the ignore call will block.
Case 2:
when istream encounters an error in a formatted input operations, it leaves the "bad" characters in the buffer, so if you retry the operation you get stuck endlessly, since the offenders are still there. The usual clear()/ignore() idiom comes to the rescue, removing the whole offending line from the input buffer.
Again, you don't put the clear()/ignore() sequence at random, but only after you get an input error from a formatted input operation (which sets the failbit of the stream).
Now, aside from these cases, it's uncommon to use cin.ignore() (unless you actually want to skip characters); don't spread it around randomly "just to be safe", because otherwise you will encounter the problem you described.
The answer can be found here.
The extraction ends when n characters have been extracted and discarded or when the character delim is found, whichever comes first. In the latter case, the delim character itself is also extracted.
So in your case, the program will not continue until a '\n' character is received.
I think cin.ignore(numeric_limits<streamsize>::max(), '\n'); is expecting a \n in the input and it doesn't find it, so you have to press Enter again for it to find it.

Trying to Read a Line of Keyboard Input in C++

I mam trying to complete a college assignment in C++ and am having trouble with what should be a very basic operation. I am trying to read a string of characters from the keyboard. This is the relevant code:
string t;
cout << endl << "Enter title to search for: ";
getline(cin, t, '\n');
I understand, that the last line is supposed to read the input buffer (cin , in this instance) and store the character in the 't' string until it reaches a new line character and then continue the program flow.
However, when I run my code in XCode, it just sort of jumps over the getline function and treats 't' as an empty string.
What's going on? I tried using cin >> t but that just read characters forever - Why cant I get this to behave?
The reason that the input operation apparently is skipped, is most probably (that means, ignoring possible peculiarities of a bugsy XCode IDE) that you have performed some input earlier and left a newline in the input buffer.
To fix that, make sure that you have emptied the input buffer after each input operation that logically should consume a line of input.
One easy way is to always use getline into a string, and then use e.g. an istringstream if you want to convert a number specification to number type.
Cheers & hth.,
From the docs page it looks like you want
cin.getline(t,256,'\n');
or something similar.
This sounds like an issue with the way Xcode is running your program. Try running your program directly from the terminal, and see if this is sufficient to fix your issue.

istream_iterator ignoring EOF (Ctrl+D) when reading chars

I'm trying to use istream_iterator for reading characters from cin. I've read that pressing Ctrl+D sends an EOF character which ends the input stream. Unfortunately, something is going wrong with it. Here's my code:
#include <iterator>
int main()
{
using namespace std;
istream_iterator<char> it(cin), eos;
while (it != eos) clog << *(it++);
}
I'm running it and typing: as df, then pressing Ctrl+D.
It outputs only asd without the last f and then hangs waiting for input. When I type gh and press Ctrl+D again, it prints the remaining f at last, and the g from next input, but again without the last h. And when I finally press Ctrl+D without typing anything, it prints the remaining h and exits.
I expected it to read asdf and exit, since I already pressed Ctrl+D at the end of this first sequence.
Why is it still waiting for input after getting EOF?
Why it doesn't print the last character read before EOF?
And why it exits only when I press Ctrl+D without typing anything before?
How does this loop need to change to make it behave in the way I expect? (i.e. stop reading immediately after getting Ctrl+D sequence in the input, no matter I typed anything before or not, and reading all characters up to the EOF).
Input iterators require special care. Rewrite your loop this way and the behavior will become similar to any other character input loop:
while (it != eos)
{
clog << *it;
it++;
}
That will take care of "Why it doesn't print the last character"
PS: as for EOF in the middle of the line, it is the POSIX-mandated behavior:
When received, all the bytes waiting to be read are immediately passed to the process without waiting for a newline, and the EOF is discarded. Thus, if there are no bytes waiting (that is, the EOF occurred at the beginning of a line), a byte count of zero shall be returned from the read(), representing an end-of-file indication.
On Unix-like systems, typing Ctrl+D triggers an end-of-file condition only at the beginning of a line (i.e., immediately after typing Enter. To trigger an end-of-file condition in the middle of a line, type Ctrl+D twice.