[ACCEPTED]-ProbIem with EOF in C-getchar
After you received an EOF from the terminal, you will not receive any additional data. There 10 is no way of un-EOF-ing the input - the 9 end of the file is, well, the end.
So you 8 should define that each variable is input 7 on a separate line, and have users press 6 enter instead of EOF. You still need to 5 check whether you have received eof, because 4 that means that the user actually typed 3 EOF, and you won't see anything else - in 2 this case, you need to break out of the 1 loop and print an error message.
EOF
isn't a character - it's a special value that the 10 input functions return to indicate a condition, that 9 the "end of file" on that input stream has 8 been reached. As Martin v. Löwis says, once 7 that "end of file" condition occurs, it 6 means that no more input will be available 5 on that stream.
The confusion arises because:
- Many terminal types recognize a special keystroke to signal "end of file" when the "file" is an interactive terminal (eg. Ctrl-Z or Ctrl-D); and
- The
EOF
value is one of the values that can be returned by thegetchar()
family of functions.
You 4 will need to use an actual character value 3 to separate the inputs - the ASCII nul character 2 '\0'
might be a good choice, if that can't appear 1 as a valid value within the inputs themselves.
I run the code on my linux box, here is 2 the result:
Enter a: qwer
asdf<Ctrl-D><Ctrl-D>
Enter b: 123
456<Ctrl-D><Ctrl-D>
Results:
a: qwer
asdf
b: 123
456
Two Ctrl-D was needed because 1 the terminal input buffer was not empty.
What you are trying is fundamentally impossible 11 with EOF.
Although it behaves like one in 10 some ways, EOF is not a character in the 9 stream but an environment-defined macro 8 representing the end of the stream. I haven't 7 seen your code, but I gather you're doing 6 is something like this:
while ((c=getchar()) != EOF) {
// do something
}
while ((c=getchar()) != EOF) {
// do something else
}
When you type the 5 EOF character the first time, to end the 4 first string, the stream is irrevocably 3 closed. That is, the status of the stream 2 is that it is closed.
Thus, the contents 1 of the second while loop are never run.
You could use the null character ('\0'
) to separate 18 the variables. Various UNIX tools (e.g. find
) are 17 capable of separating their output items 16 in this way, which would suggest that it's 15 a fairly standard method.
Another advantage 14 of this is that you can read the stream 13 into a single buffer and then create an 12 array of char*
s to point to the individual strings, and 11 each string will be correctly '\0'
-terminated 10 without you having to change anything in 9 the buffer manually. This means less memory 8 allocation overhead, which may make your 7 program run noticeably faster depending 6 on how many variables you're reading. Of 5 course, this is only necessary if you need 4 to hold all the variables in memory at the 3 same time — if you're dealing with 2 them one-at-a-time, you don't get this particular 1 advantage.
Rather than stopping reading input at EOF 6 -- which isn't a character -- stop at ENTER.
while((c = getchar()) != '\n')
{
if (c == EOF) /* oops, something wrong, input terminated too soon! */;
a[x] = c;
x++;
}
EOF is a signal that 5 the input terminated. You're almost guaranteed 4 that all inputs from the user end with '\n': that's 3 the last key the user types!!!
Edit: you 2 can still use Ctrl-D and clearerr()
to reset the input 1 stream.
#include <stdio.h>
int main(void) {
char a[100], b[100];
int c, k;
printf("Enter a: "); fflush(stdout);
k = 0;
while ((k < 100) && ((c = getchar()) != EOF)) {
a[k++] = c;
}
a[k] = 0;
clearerr(stdin);
printf("Enter b: "); fflush(stdout);
k = 0;
while ((k < 100) && ((c = getchar()) != EOF)) {
b[k++] = c;
}
b[k] = 0;
printf("a is [%s]; b is [%s]\n", a, b);
return 0;
}
$ ./a.out Enter a: two lines (Ctrl+D right after the next ENTER) Enter b: three lines now (ENTER + Ctrl+D) a is [two lines (Ctrl+D right after the next ENTER) ]; b is [three lines now (ENTER + Ctrl+D) ] $
How do you enter null in the program?
You 3 can implement the -print0 function using:
putchar(0);
This 2 will print an ASCII nul character '\0' to 1 sdtout.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.