Trying with EOF in C

I am writing a program that should read two lines, which may contain line breaks and various other characters. Therefore, I use EOF (Ctrl-Z or Ctrl-D) to complete the line.

This works well with the first variable, but with the second variable, however, it seems problematic, since it is obvious that something is stuck in the input buffer and the user cannot enter anything.

I tried to clear the buffer with while (getchar() != '\n'); and a few similar options, but nothing seemed to help. All attempts at cleaning led to an infinite loop, and without cleaning, adding a second variable is impossible.

The characters for both variables are read in a loop like this: while((c = getchar()) != EOF) , which means that it is EOF, that I am stuck in my buffer. Or does it somehow affect the behavior of the program? Is there something wrong with the logic used?

I begin to feel a little desperate after several hours of struggling with this.

The code:

 #include <stdio.h> #include <string.h> int main(void) { int x = 0; int c; char a[100]; char b[100]; printf("Enter a: "); while((c = getchar()) != EOF) { a[x] = c; x++; } a[x] = '\0'; x = 0; /*while (getchar() != '\n'); - the non-working loop*/ printf("\nEnter b: "); while((c = getchar()) != EOF) { b[x] = c; x++; } b[x] = '\0'; printf("\n\nResults:\na: %s\n", a); printf("b: %s\n", b); return(0); } 
+4
c string newline eof getchar
Oct 25 '09 at 21:16
source share
7 answers

After you received EOF from the terminal , you will not receive any additional data . Unable to disable EOF input - end of file, well, end.

So, you must determine that each variable is entered as a separate line, and users should press Enter instead of EOF. You still need to check if you received eof, because it means that the user really typed EOF, and you won’t see anything - in this case you need to break out of the loop and display an error message.

+11
Oct 25 '09 at 21:20
source share

EOF not a character — it is a special value returned by input functions to indicate that the “end of file” on this input stream has been reached. As Martin vs. Lewis says, when this “end of file” condition occurs, it means that there will be no more input in this stream.

Confusion arises from the fact that:

  • Many types of terminals recognize special keystrokes to signal “end of file” when “file” is an interactive terminal (for example, 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 will need to use the actual value of the character to separate the inputs - the ASCII character nul '\0' may be a good choice if it cannot be displayed as a valid value inside the inputs themselves.

+2
25 Oct '09 at 21:32
source share

I run the code in my linux window, here is 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-Ds were needed because the terminal input buffer was not empty.

+1
Oct 25 '09 at 22:26
source share

What you are trying is fundamentally impossible with EOF.

Although it behaves as one in some way, EOF is not a symbol in the stream, but a macro defined by the environment representing the end of the stream. I have not seen your code, but you think you are doing something like this:

 while ((c=getchar()) != EOF) { // do something } while ((c=getchar()) != EOF) { // do something else } 

When you enter the EOF character for the first time to complete the first line, the stream is permanently closed. That is, the status of the stream is that it is closed.

Thus, the contents of the second while loop never starts.

0
Oct. 25 '09 at 21:30
source share

You can use the null character ( '\0' ) to separate the variables. Various UNIX tools (such as find ) are able to separate their output elements in a way that suggests this is a fairly standard method.

Another advantage of this is that you can read the stream into a single buffer, and then create a char* array to point to individual lines, and each line will be correctly '\0' -terminated without having to change everything in the buffer manually. This means that the overhead is less, which can significantly speed up your program depending on the number of variables you are reading. Of course, this is only necessary if you need to store all the variables in memory at the same time - if you deal with them one on one, you will not get this special advantage.

0
Oct 25 '09 at 21:30
source share

Instead of stopping reading input in EOF - which is not a character - it stops 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 the input is completed. You are almost guaranteed that all user entries end in "\ n": the last key that the user enters !!!




Edit: you can still use Ctrl-D and clearerr() to reset the input 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)
 ]
 $ 
0
Oct 25 '09 at 21:50
source share

How to enter null value in the program?

You can implement the -print0 function using:

 putchar(0); 

This will print the ASCII character nul '\ 0' in sdtout.

0
Oct 26 '09 at 7:01
source share



All Articles