fgetc stops when recognizing new line (\n)

Lior picture Lior · Nov 7, 2012 · Viewed 13.1k times · Source

I have this code:

while( (cCurrent = fgetc(fp)) != EOF)
{

}

The problem is, when it hits a new line it stops reading.

What would be a good way to ignore the newline character?

Edit:

I'm trying to create a file crypter. It is able to encrypt the file, but the decrypt process won't work. It works till the end of the first line, but it won't continue to the next characters in the file.

For example, for the text file:

Foo  
Bar

After the encryption the result is:

Xu||Gb|t

After the decryption the result is:

FooRqb

I concluded that the new line char was the problem. maybe it wasn't.

My code is:

/* check if the file is openable */
if( (fp = fopen(szFileName, "r+")) != NULL )
{
    /* save current position */
    currentPos = ftell(fp);
    /* get the current byte and check if it is EOF, if not then loop */
    while( (cCurrent = fgetc(fp)) != EOF)
    {
        /* XOR it */
        cCurrent ^= 0x10;
        /* take the position indicator back to the last position before read byte */
        fseek(fp, currentPos, SEEK_SET);
        /* set the current byte */
        fputc(cCurrent, fp);
        /* reset stream for next read operation */
        fseek(fp, 0L, SEEK_CUR);
        /* save current position */
        currentPos = ftell(fp);
    }

Answer

Mike picture Mike · Nov 7, 2012

It took me a while, but I finally got what you're trying to do.

Input file:

Hello

encrypt by running your code:

Xu||(non displayable character)

Decrypt by running your code again:

Hello

So how this works:

0x48 XOR 0x10 = 0100 1000 (H)---+
                0001 0000       |
                ---------       V
                0101 1000 = 58 (X)

0x58 XOR 0x10 = 0101 1000 (X)---+
                0001 0000       |
                ---------       V
                0100 1000 = 48 (H)

The problem comes in with you're working with the new line character '\n' which is 0xA16

Input file:

Hello
You

This works fine up until the '\n' then we get new line:

0xA XOR 0x10 =  0000 1010 ('\n')---+
                0001 0000          |
                ---------          V
                0001 1010 = 1A (substitute character)

The substitute character In DOS operating systems, this character is used to indicate the end of a file (EOF)

So this fails because you're working on Windows. So you need to do special checking for the '\n' case in your encryption/decryption and not blindly XOR it.

One easy fix, you could simply do something like:

while( (cCurrent = fgetc(fp)) != EOF)
{
    /* XOR it if it's not a '\n'*/
    if(cCurrent != '\n')
      cCurrent ^= 0x10;