[ACCEPTED]-ProbIem with EOF in C-getchar

Accepted answer
Score: 13

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.

Score: 2

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 the getchar() 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.

Score: 1

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.

Score: 0

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.

Score: 0

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.

Score: 0

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)
]
$
Score: 0

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