[prog] C problem I am unable to solve

Almut Behrens almut-behrens at gmx.net
Thu May 12 06:47:52 EST 2005


On Wed, May 11, 2005 at 01:18:21PM -0400, Angelina Carlton wrote:
> /* Write a program that displays the contents of a file 20
>    lines at a time, after which it pauses and waits for
>    the user to enter q to quit or any other key to keep
>    going.*/
> 
> So my program asks for a file, checks it exists and and 
> makes sure it has an EOF
> 
> the function I use to do the reading is giving me problems
> though, it seems using either fgets or getc I can read up 
> to 20 lines but the second time it jumps to 40 lines at a
> time without asking at the 20 line mark,
> 
> int read_file(FILE *inputfile)
> {
> 
>   int i; /* number of lines to display at one time */
>   char c;
>   char q;
> 
>   while(! (feof(inputfile)) ) { /* until the end of the file*/
>     for (i = 0; i <= 19; ++i) {
>       while ( (c = getc(inputfile)) != '\n' )
>         putc(c, stdout); /* display the line */
>         putc('\n', stdout);
>       if(i == 19) { /* stop at 20 */
>         printf("press 'q' to quit, any other key to continue:\n");
>         scanf("%c", &q);
>         if (q == 'q') {
>           return 0;
>         }
>       }
>     }
>   }
>   return 0;
> }

I think Dan has already spotted the main problem...
So, I'd just like to add a little comment on the loop structure:

Currently you have this (in simplified form)

  while(...) {
    for (i = 0; i <= 19; ++i) {
      if(i == 19) {
        /* wait for keypress */
      }
    }
  }

Alternatively, you could write

  while(...) {
    for (i = 0; i <= 19; ++i) {
    }
    /* wait for keypress */
  }

because the program flow will drop out of the for-loop anyway, after 20
iterations, so you can simply wait for the keypress there, instead of
having to test for i==19 within the loop.

Yet another way would be this

  c=0;
  while(...) {
    if((c++ % 20) == 0) {
      /* wait for keypress */
    }
  }

This is looping over the whole file, using the modulo operator %
(= remainder of integer division) applied on a global line counter to
determine when we've reached a multiple of 20 lines -- in that case
c % 20 will be zero.

Of course, your method works too, but a typical programmer would find
the other ones somewhat easier to read -- probably ;)

Cheers,
Almut



More information about the Programming mailing list