我有这段代码:
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);
}
答案 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)