3

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);
    }
4

4 に答える 4

7

しばらく時間がかかりましたが、やっとあなたがやろうとしていることがわかりました。

入力ファイル:

Hello

コードを実行して暗号化します。

Xu||(non displayable character)

コードを再度実行して復号化します。

Hello

それで、これがどのように機能するか:

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)

'\n'問題は、 0xA16である改行文字を使用しているときに発生します。

入力ファイル:

Hello
You

これは、それまでは正常に機能し、'\n'新しい行を取得します。

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

置換文字DOSオペレーティングシステムでは、この文字はファイルの終わり(EOF)を示すために使用されます

したがって、Windowsで作業しているため、これは失敗します。'\n'したがって、暗号化/復号化のケースについて特別なチェックを行う必要があり、盲目的にXORする必要はありません。

簡単な修正の1つは、次のようなことです。

while( (cCurrent = fgetc(fp)) != EOF)
{
    /* XOR it if it's not a '\n'*/
    if(cCurrent != '\n')
      cCurrent ^= 0x10;
于 2012-11-07T16:38:19.153 に答える
4

On Windows, lines in text files are separated by \r\n, not just \n, and files are opened by default in "text" mode, which automatically translates \r\n to \n when reading the file (see fopen in Visual Studio 2012).

Since you're interpreting your file as a sequence of bytes (because of the XOR operation), you don't want this behavior - each time there is a line ending, you're losing a byte of data. You should open your file in "binary" mode to suppress this behavior:

fp = fopen(szFileName, "rb+")

This will also suppress the behavior noted by @Mike where reading a \x1A character is interpreted as the end of file.

于 2012-11-07T16:50:08.377 に答える
1

fgetcEOFman fgetc(3)からの改行文字だけで停止するべきではありません:

fgetc()は、ストリームから次の文字を読み取り、それをintにキャストされたunsigned char、またはファイルの終わりまたはエラーのEOFとして返します。

ただし、次のように記述してください。

while( (cCurrent = fgetc(fp)) != '\n' && cCurrent != EOF)

改行文字で停止するため、最初の文字は正しいです。

while( (cCurrent = fgetc(fp)) != EOF)
于 2012-11-07T15:48:13.540 に答える
0

これはfgetc()の正しい動作ではありません。

2番目のコードスニペットは、改行を押すと実際に壊れてしまうため、不可解です。それで、それが問題をどのように解決するかは私には謎です。

ロジックが少し混乱しているのではないかと思います。

于 2012-11-07T15:48:36.017 に答える