Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: while loop vs do while loop reading from the file issue Date: Wed, 07 Dec 2016 09:53:53 -0800 Organization: None to speak of Lines: 72 Message-ID: References: <52f1c174-6af1-4fda-9ff8-a5e2cf507b5f@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="f53e7a1e34684316d0e01429e9e9bbea"; logging-data="2193"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+PyuaR90hzeCqTkSGKFZxJ" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:wBrm+pwf9Nu8oJXOm389dsDo+f0= sha1:MTyX/peOeYYis02kbdgDrVWnqiI= Xref: csiph.com comp.lang.c:98279 Alla _ writes: > Please, take a look at the same program but two versions of it. The > first version is is written by Deitel&Deitel; in the second version I > would like to change the while loop into a do while one, but is it > possible to set a condition of the while statement such that the loop > ends right before the EOF, i.e. to escape printing the last line > twice? Please, note that I understand that the current version (2) > does print the last line twice because the loop ends only when EOF is > true, and that happens on the forth iteration. Is there a reasonably > simple way to avoid double printing of the last line, or do while loop > won't work in such circumstances? Why do you want to change a while loop to a do-while loop? A while loop will execute zero or more times. A do-while loop tests the condition at the bottom, and executes at least once. A text file can contain zero or more lines. A loop that processes each line should execute N times, where N is the number of lines in the input. A while loop is the right tool for reading input from a (possibly empty) file. A do-while loop is not. [...] > (1) original program: > > // Reading and printing a sequential file [...] > // while not end of file > while (!feof( cfPtr )) > { > printf( "%-10d%-13s%7.2f\n", account, name, balance ); > fscanf( cfPtr, "%d%29s%lf", &account, name, &balance ); > } Hmm. Did Deitel&Deitel really use this method? (I don't have a copy.) If so, do they show a later example that doesn't use feof() to determine when the loop is finished? The feof() function is not intended to be used to control an input loop. It, along with ferror(), can be used after a loop finishes to determine why it finished. The value returned by feof() becomes true *after* an input failure occurs. An input loop should test the value returned by the input function (getchar(), fgets(), fscanf(), whatever you're using). Every input function has a way to tell you that there was no more input; you'll have to read the documentation for whatever function you're using. fscanf() returns the value EOF on certain errors; otherwise it returns the number of items scanned. Since the call here attempts to scan 3 items, you can assume you're done if it returns any value other than 3. Typically you'll want to put the input call in the condition. For example, the usual way to read input a character at a time is: while ((c = getchar()) != EOF) { /* ... */ } Note that if there's an I/O error on input, ferror() will return true after the error occurs and feof() will *never* return true, so you'll have an infinite loop. [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"