识别新行时fgetc停止(\ n)

时间:2012-11-07 15:43:27

标签: c file newline fgetc

我有这段代码:

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

}

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

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

编辑:

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

例如,对于文本文件:

Foo  
Bar

加密后,结果为:

  

许|| GB |吨

解密后,结果为:

FooRqb

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

我的代码是:

/* 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 个答案:

答案 0 :(得分: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)

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

因此失败,因为您正在使用Windows。因此,您需要对加密/解密中的'\n'情况进行特殊检查,而不是盲目地对其进行异或。

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

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

答案 1 :(得分:3)

在Windows上,文本文件中的行由\r\n分隔,而不仅仅是\n,默认情况下会以“文本”模式打开文件,这会自动将\r\n翻译为{{} 1}}在阅读文件时(见fopen in Visual Studio 2012)。

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

\n

这也会抑制@Mike注意到的行为,其中读取fp = fopen(szFileName, "rb+") 字符被解释为文件结尾。

答案 2 :(得分:1)

fgetc不应仅停留在人fgetc(3)EOF处的换行符:

  

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

但是如果你这样写的话:

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

将在换行符处停止,因此第一个是正确的:

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

答案 3 :(得分:0)

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

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

我怀疑你的逻辑混淆了一点。