3

我有这个代码:

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

}

问题是,当它遇到新行时,它会停止读取。

什么是忽略换行符的好方法?

编辑:

我正在尝试创建一个文件加密器。它能够加密文件,但解密过程不起作用。它一直工作到第一行的末尾,但不会继续到文件中的下一个字符。

例如,对于文本文件:

Foo  
Bar

加密后的结果是:

许||Gb|t

解密后的结果是:

FooRqb

我的结论是新行字符是问题所在。也许不是。

我的代码是:

/* 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'问题在于您正在使用0xA 16的换行符

输入文件:

Hello
You

这工作正常,直到'\n'我们得到新行:

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

替换字符在 DOS 操作系统中,此字符用于指示文件的结尾 (EOF)

所以这失败了,因为你在 Windows 上工作。因此,您需要对加密/解密中的情况进行特殊检查,'\n'而不是盲目地对其进行异或。

一个简单的解决方法,您可以简单地执行以下操作:

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

在 Windows 上,文本文件中的行由 分隔\r\n,而不仅仅是\n,并且文件默认以“文本”模式打开,读取文件时会自动转换\r\n为(参见Visual Studio 2012 中的 fopen)。\n

由于您将文件解释为字节序列(由于 XOR 操作),因此您不希望出现这种行为 - 每次有一行结束时,您都会丢失一个数据字节。您应该以“二进制”模式打开文件以抑制此行为:

fp = fopen(szFileName, "rb+")

这也将抑制@Mike 指出的读取\x1A字符被解释为文件结尾的行为。

于 2012-11-07T16:50:08.377 回答
1

fgetc不应该在换行符处停止,只能在EOFman fgetc(3)处停止:

fgetc() 从流中读取下一个字符并将其作为 unsigned char 转换为 int 或文件末尾的 EOF 或错误返回。

但是,如果你这样写:

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

它将在换行符处停止,所以第一个是正确的:

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

这不是fgetc()的正确行为。

您的第二个代码片段令人费解,因为它实际上在您换行时会中断。所以如何解决这个问题对我来说是个谜。

我怀疑你的逻辑有点混乱。

于 2012-11-07T15:48:36.017 回答