我用“有效”标记的答案解决了这个问题,但略有不同。我使用fopen(file, "r+b")
而不是fopen(file, "r+")
打开文件。 b
以二进制模式打开它,并且不会搞砸文件。
我正在做一个简单的程序,我打电话给#34; fuzzer" 这是我的代码:
int main(int argc, char* argv[]){
// Here go some checks, such as argc being correct, etc.
// ...
// Read source file
FILE *fSource;
fSource = fopen(argv[1], "r+");
if(fSource == NULL){
cout << "Can't open file!";
return 2;
}
// Loop source file
char b;
int i = 0;
while((b = fgetc(fSource)) != EOF){
b ^= 0x13;
fseek(fSource, i++, SEEK_SET);
fwrite(&b, 1, sizeof(b), fSource);
}
fclose(fSource);
cout << "Fuzzed.";
return 0;
}
但是,它不起作用。之前,我使用了while(!feof)
,但它也没有工作,I saw that it's not correct,所以我将其更改为(b = fgetc()) != EOF
(我认为它是正确的,对吧?) 。
当我运行它时,它会卡在无限循环上,并且它不会修改原始文件,而是向它添加波形(并且文件会快速增加其大小,直到我停止它)。如果我从&#34; a +&#34;更改开放模式到&#34; r +&#34;,它只是删除文件的内容(但它至少不会陷入无限循环)。
注意:我知道这不是任何混淆或加密。我没有尝试编码文件,只是练习使用C ++和文件。
答案 0 :(得分:2)
在使用GCC 4.9.0的Ubuntu 12.04衍生产品上测试时,此代码对我有用:
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
if (argc != 2)
{
cerr << "Usage: " << argv[0] << " file\n";
return 1;
}
FILE *fSource = fopen(argv[1], "r+");
if (fSource == NULL)
{
cerr << "Can't open file: " << argv[1] << "\n";
return 2;
}
int c;
int i = 0;
while ((c = fgetc(fSource)) != EOF)
{
char b = c ^ 0x13;
fseek(fSource, i++, SEEK_SET);
fwrite(&b, 1, sizeof(b), fSource);
fseek(fSource, i, SEEK_SET);
}
fclose(fSource);
cout << "Fuzzed: " << argv[1] << "\n";
return 0;
}
报告文件名;它将错误报告给标准错误(cerr
);它使用int c;
来阅读该字符,但将其复制到char b
以便fwrite()
正常工作。当运行(自己的)源代码的副本时,第一次输出看起来像乱码,第二次恢复原始。
此循环使用fputc()
代替fwrite()
,也可以在不需要中间变量b
的情况下运行:
while ((c = fgetc(fSource)) != EOF)
{
fseek(fSource, i++, SEEK_SET);
fputc(c ^ 0x13, fSource);
fseek(fSource, i, SEEK_SET);
}
在C标准强制要求在写入和之后使用fseek()
。我不确定这是否是您遇到麻烦的主要原因,但理论上它可能是其中一个问题。
答案 1 :(得分:1)
您需要int b;
。 char
永远不会是EOF
。 The manual描述了这一切。总而言之,这样的事情:
for (int b, i = 0; (b = fgetc(fSource)) != EOF; ++i)
{
unsigned char x = b;
x ^= 0x13;
fseek(fSource, i, SEEK_SET);
fwrite(&x, 1, 1, fSource);
fseek(fSource, i + 1, SEEK_SET);
}
您还应该使用模式"rb+"
打开文件,并在每次读写之间进行搜索(感谢@Jonathan Leffler)。