C++ ifstream/fstream 损坏数据
我是 C++ 新手,我必须为学校做作业。
我需要在不使用 api 调用或系统集成命令的情况下复制二进制* 文件。在学校我们使用 Windows 机器。
我搜索了一下,发现不使用任何 api 复制数据的最佳方法是使用 iostream (ifstream/fstream) 这是我正在使用的代码:
int Open(string Name){
int length;
char * buffer;
ifstream is;
fstream out;
FILE* pFile;
is.open (Name.c_str(), ios::binary );
// get length of file:
is.seekg (0, ios::end);
length = is.tellg();
is.seekg (0, ios::beg);
// allocate memory:
buffer = new char [length];
// read data as a block:
is.read (buffer,length);
is.close();
pFile = fopen ( "out.exe" , "w" );
fclose(pFile);
out.open("out.exe", ios::binary);
out.write( buffer, length);
out.close();
delete[] buffer;
return 0;
}
out.exe 工作不正常,在 winhex.exe 中查看后 我看到数据已被修改,而我没有对其进行任何操作
有人可以帮助我吗?
*该文件是一个简单的 hello world 程序,它的消息框为“hello world”
编辑:
抱歉我没有反应,它正在睡觉。 无论如何,我已经在十六进制编辑器中打开了两个程序(结果和原始)。 似乎我尝试这一行的所有内容:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000200 4C 00 00 00 00 30 00 00 00 02 00 00 00 0D 0A 00 L 0
更改为:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000200 4C 00 00 00 00 30 00 00 00 02 00 00 00 0A 00 00 L 0
正如您在读取或写入过程中可以或看不到的那样,一个字节正在被删除(或添加,有时也会发生)
I'm new to C++ and I've to do an assignment for school.
I need to copy a binary* file without using api calls or system integrated commands. At school we use a windows machine.
I've searched around a bit, and I found out that the best way to copy data without using any api's is to use iostream (ifstream/fstream)
Here's the code I'm using:
int Open(string Name){
int length;
char * buffer;
ifstream is;
fstream out;
FILE* pFile;
is.open (Name.c_str(), ios::binary );
// get length of file:
is.seekg (0, ios::end);
length = is.tellg();
is.seekg (0, ios::beg);
// allocate memory:
buffer = new char [length];
// read data as a block:
is.read (buffer,length);
is.close();
pFile = fopen ( "out.exe" , "w" );
fclose(pFile);
out.open("out.exe", ios::binary);
out.write( buffer, length);
out.close();
delete[] buffer;
return 0;
}
out.exe isnt working properly, and after looking at it in winhex.exe
I see that the data has been modefied, while I'm not doing anything with it
Can anyone help me?
*the file is a simple hello world program, it messageboxes "hello world"
EDIT:
Sorry for my unresponsiveness, It was sleeping.
Anyways, I've opened both (the result and the original) programs inside an hex editor.
It seems that with everything I try this line:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000200 4C 00 00 00 00 30 00 00 00 02 00 00 00 0D 0A 00 L 0
Changes into this:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000200 4C 00 00 00 00 30 00 00 00 02 00 00 00 0A 00 00 L 0
As you can or cannot see somehow during the reading or writing process a byte is being removed (or added, that sometimes happens as well)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
未指定仅将
ios_base::binary
传递给fstream
的 ctor(in
和/或out
也必须提供)。为了避免这种情况,您可以使用
ofstream
(注意 exra 'o')作为out
而不是fstream
。作为奖励,这将避免需要首先使用“w”标志进行fopen
,因为ofstream
的 ctor 默认创建文件。Passing only
ios_base::binary
tofstream
's ctor is not specified (in
and/orout
must be supplied too).To avoid that, you could use
ofstream
(note the exra 'o') forout
instead offstream
. As a bonus, this would avoid the need to firstfopen
with the "w" flag sinceofstream
's ctor creates the file by default.is.read(buffer, length) 不保证读取 length 字节。
我忘记了 out.write 是否也是如此。
is.read(buffer, length) is not guaranteed to read length bytes.
I forget if the same is true for out.write or not.
让我们把它变得更整洁一点:
Lets make that a bit neater:
通常,文件以换行符结尾。 0d0a(“\r\n”)可能不是源文件的可读部分。 Windows 通常使用“\r\n”作为换行符,而 UNIX 仅使用“\n”。由于某种原因,当它写入一个新文件时,它仅使用 0a 作为最后的换行符。如果读入并复制第一次写入的文件,看看会发生什么可能会很有趣。
简短的回答是,这正是您使用 Windows 系统时出现的问题。 :D
要破解它,您总是可以无条件地编写一个额外的“\r”作为最后输出的内容。
Generally, files end in a newline. That 0d0a ("\r\n") might not be a readable part of the source file. Windows usually uses "\r\n" for newline, while UNIX uses just "\n". For some reason, when it writes a new file, it's using just 0a for the final newline. It might be interesting to see what happens if you read in and copy the file you wrote the first time.
The short answer is, this is just the kind of problem that crops up when you use a Windows system. :D
To hack it, you could always unconditionally write an extra "\r" as the last thing you output.
我认为这样
就可以了。
I think that
would do the trick.