简体   繁体   中英

EOF - scanf and printf

I'm tring to do a simple exercise here, but i need to understand how EOF works first.

void main()
{
    char s1[1000];
    while (scanf("%s", s1)!=EOF)
        ;
    printf("%s",s1);
}

The idea is to have multiple lines in input, and display them.

The problem I have is that if I put

Hello World
This is stackoverflow

When printf is called, it only prints

stackoverflow

Why isn't it printing everything and how do I make it print?

Regards

Remove the semicolon ; :

    while (scanf("%s", s1)!=EOF)
        printf("%s",s1);

Note that this will still exhibit odd behavior at end of file depending on how it ends exactly. Furthermore, it splits the input into words, which are separated by spaces or new lines. You may want to simply split into lines.

So you may be better served with for instance:

    while (gets(s1)!=NULL)
        puts(s1);

This code fragments reads your input line by line until end-of-file.

To read everything (or as much as your buffer can hold), you can use:

    char s1[1000] = "";
    fread(s1, sizeof(s1) - 1, 1, stdin);
    puts(s1);

However, my preferred method of reading a text file is:

    using namespace std;
    string line;
    while (getline(cin, line))
    {
        cout << line << endl;
    }

That is because usually I want to process a file line by line, and getline with a string ensures the line buffer is always big enough.

You probably want this:

  char s1[1000][20];

  int i = 0 ;

  while (!feof(stdin))
     fgets(s1[i++], 20, stdin) ;

  int j ;
  for (j = 0; j < i; j++)
    printf("%s\n", s1[j]);

Here you can enter at most 1000 lines that are maximum 19 characters long.

What you have is a loop that reads words into a buffer until it reaches EOF (and does nothing with those words), followed by a printf to print the contents of the buffer. The printf is after the loop (not in it), so executes once after the loop completes. At that time, the buffer will contain the last word read, so that is what gets printed.

The EOF return test means "nothing more to be read", which isn't necessarily an end of file (might be an error condition of some kind), but in practice that distinction can be ignored. Looping until your reading function returns EOF or NULL (depends on function) is good practice.

If you want to print each word as it is read, you need to put a printf in the loop.

If you want to store the words for later processing, you need to store them somewhere. That means declaring some storage space, or allocating space on the heap, and some bookkeeping to track how much space you've used/allocated.

If you want lines rather than words, you should use fgets instead of scanf("%s" . Note that fgets returns NULL rather than EOF when there's nothing more to be read.

Because it only prints the last thing that is read from the file ("stackoverflow"). This is caused by the semicolon after the end of your while(...); - this means that you are doing while(...) { /* do nothing */} - which is probably not what you wanted

Also, printf("%s",s1)!='\\0'; makes no sense at all. For one thing, printf returns the number of characters printed - '\\0' is the value zero written as a character constant. And of course, doing != 0 of the result without some sort of use of the comparison is pretty much pointless too.

Use fgets instead of scanf if you want to read one line at at time. scanf will stop reading when it finds a whitespace. fgets will read till the end of the line.

Use fgets() . Simple and sweet

char buf[1000];
while (fgets(buf, sizeof buf, stdin) != NULL) {
  fputs(buf, stdout);
}

Here is how end-of-file works in C. The input channels are called input streams ; disk files and stdin are both input streams. The "end-of-file" state is a flag that a stream has, and that flag is triggered when you try to read from a stream, but it turns out there are no more characters in the stream, and there never will be any more. (If the stream is still active but just waiting for user input for example, it is not considered to be end-of-file; read operations will block).

Streams can have other error states, so looping until "end-of-file" is set is usually wrong. If the stream does go into an error state then your loop will never exit (aka. "infinite loop").

The end-of-file state can be checked by feof . However, some input operations also can signal an error as well as, or instead of, returning the actual data they were intended to read. These functions can return the value EOF . Usually these functions return EOF in both cases: end-of-file, and stream error. This is different to feof which only returns true in the case of end-of-file.

For example, getchar() and scanf will return EOF if it was end-of-file, but also if the stream is in an error state.

So it is OK to use getchar() 's result as a loop condition, but not feof on its own.

Also, it is sometimes not OK to use scanf() != EOF as a loop condition. It's possible that there is no stream error, but just that the data you requested wasn't there. For example, if you scan for "%d" but there are letters in the stream. Instead, it's better to check for successful conversion (scanf returns the number of successful conversions it performed). Then when you exit your loop, you can go on to call feof and ferror to see whether it was due to end-of-file, or error, or just unexpected input.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM