3

I'm playing around with fgetc and was wondering how I would get my loop to print the line section once then print the first 16 characters.

Here is my code:

int main(int argc, char * argv[])
{
    FILE *fp;

    if((fp = fopen(argv[1], "rb+")) == '\0')
    {
        perror("fopen");
        return 0;
    }

    getchar(fp);

    return 0;
}

void getchar(FILE *fp)
{
    int c;
    size_t linecount = 0;

    while((c = fgetc(fp)) != EOF)
    {
        printf("line : ");
        printf("%c ", c);
        linecount++;

        if(linecount == 16)
        {
            printf("\n");
        }
    }
}

I want my output to be something like:

 line: ? 5 d s d a d 0 0 0 0 0 0 0 0 0 0 0
 line: a d s x c v d 0 0 0 0 0 0 0 0

I've tried printing the characters using this for loop:

for(i = 0; i < 16; i++)
{
   printf("%c ", c);
}

But that didn't get the other characters, because the loop was still concentrated on the first character

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
user798774
  • 403
  • 2
  • 8
  • 20

2 Answers2

6

Firstly, there is already a standard function called getchar() defined in <stdio.h> - you must change the name of your function, or your may get some very strange behaviour.

Secondly, it seems to me that what you want to do is:

  • Print out "line: ";
  • Read a character and print it, until end of file or you have printed 16 characters;
  • Print out "\n".

This would translate into code form as:

printf("line : ");

while (linecount < 16 && (c = fgetc(fp)) != EOF)
{
    printf("%c ", c);
    linecount++;
}

printf("\n");
caf
  • 233,326
  • 40
  • 323
  • 462
  • 2
    Could be changed to print `"line:"` and then " %c" in the loop if the excess space character on the end of each line were undesirable. – Chris Lutz Jul 08 '11 at 00:31
3
if((fp = fopen(argv[1], "rb+")) == '\0')

The ASCII NUL character is not the same as the NULL pointer. This should be == NULL, or if(!(fp = fopen(argv[1], "rb+"))) /* ... */, whichever you think is easier to read. The return 0 in this clause should probably be return 1, so it is easier to work with your program in standard pipelines. (Errors in programs are made clear by a non-zero return value. Yes, it's a bit backwards, but there's good reason.)

void getchar(FILE *fp)

Oops. getchar(3) already exists in the <stdio.h> header. Redefining it is not a good idea. (It might work now, but a future modification might completely fail for non-obvious reasons.)

I've re-worked the loop in the gc() routine a little, it should do what you need:

#include <stdio.h>

void gc(FILE * fp);

int main(int argc, char *argv[])
{
    FILE *fp;

    if ((fp = fopen(argv[1], "rb+")) == NULL) {
        perror("fopen");
        return 1;
    }

    gc(fp);

    return 0;
}

void gc(FILE * fp)
{
    int c;
    size_t linecount = 0;

    while ((c = fgetc(fp)) != EOF) {
        if (linecount == 0)
            printf("line : ");

        printf("%c ", c);

        if (++linecount == 16) {
            printf("\n");
            linecount = 0;
        }
    }
}

The output when run on itself:

$ ./printer printer.c | head
line : # i n c l u d e   < s t d i o . 
line : h > 

 v o i d   g c ( F I L E 
line :   *   f p ) ; 

 i n t   m a i 
line : n ( i n t   a r g c ,   c h a r 
line :   * a r g v [ ] ) 
 { 
Community
  • 1
  • 1
sarnold
  • 102,305
  • 22
  • 181
  • 238
  • 1
    Note that `'\0'` is an integer constant expression with value 0, and therefore is a valid null pointer constant (but still indicates considerable confusion). – caf Jul 08 '11 at 00:43