gregh
gregh

Reputation: 37377

Understanding type casting in c

I'm following a book on c, and I come to some code that reads a file with 3 lines of text.

#include <stdio.h>

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

    fp = fopen( "../../My Data File", "r" );

    if ( NULL == fp ) {
        printf( "Error opening ../My Data File" );
    } else {
        while ( (c = fgetc( fp )) != EOF )
            putchar ( c );

        fclose( fp );
    }

    return 0;
}

I tried to modify it, to detect each line and print the current line number by making these modifications.

int line = 1;

while ( (c = fgetc( fp )) != EOF ){
    if (c == '\n'){
        printf(" LINE %d", line);
        putchar( c );
        line++;
    }
    else {
        putchar ( c );
    }
}

But it failed to print the line #, till I changed the type of the variable c to a char. Is there a way to check for a newline while still using c as an int?

What is the proper way to check for a newline?

Upvotes: 1

Views: 439

Answers (2)

Alok Singhal
Alok Singhal

Reputation: 96221

Your code prints line numbers at the end of a line, right before printing the '\n', because of the way you have written the loop. Otherwise, your code should work.

If you want your code to print the line numbers at the beginning, you can do something like (untested):

int line_num_printed = 0; /* indicating if we printed a line number */
int line = 1;

while ((c = fgetc(fp)) != EOF) {
    if (!line_num_printed) {
        printf("LINE %d: ", line);
        line_num_printed = 1;
    }
    putchar(c);
    if (c == '\n'){
        line++;
        line_num_printed = 0;
    }
}

If there is something else that "doesn't work", you should post complete code and tell us what doesn't work.

Edit: The proper way to check a character for a newline is to test against '\n'. If the character came from a file, you should also make sure you open the file in text mode, i.e., without a b in the second argument to fopen().

Also, you want c to be of type int, not char. This is because in C, EOF is a small negative number, and if char is unsigned, comparing it against a negative number convert the value of EOF to a positive value (equal to EOF + UCHAR_MAX + 1 most likely). Therefore, you should not change c to char type. If you do, the comparison c != EOF might be false even when fgetc() returns EOF.

Upvotes: 1

Jaime Garcia
Jaime Garcia

Reputation: 7116

Usually the integer code for a new line ('\n') is 13. So you could do ( if (c == 13) ), but also note that windows files use 2 characters to define a new line '\r' and '\n'. The integer character for '\r' is 10. But basically yes you can keep 'c' as an int and just compare against 13.

Upvotes: 0

Related Questions