问题
I have made the previous problem simpler to get the answer and understand it completely.
The problem is that I want to write a C++ program that converts an ordinary text file into binary and then reads that binary file and converts it to a text file so that this text file equals to first text file. I have wrote this simple code for it.
int main()
{
string name1 = "first", name2 = "sec", name3 = "third";
int j = 0, k = 0;
ifstream ifs(name1.c_str()); // Here I want to read from the ordinary text file (name1).
ifs >> j; // Now j equals to 5 because name1 contains digit 5.
ifs.close();
ofstream ofs(name2.c_str(), ios::binary);
ofs.write(as_bytes(j), sizeof(int)); // Here I want to write that j to name2 file in binary mode.
ofs.close();
ifstream ifs1(name2.c_str(), ios::binary); // Here I want to read from that binary file (name2).
ifs.read(as_bytes(k), sizeof(int)); // Here I hope k becomes 5.
ofstream ofs1(name3.c_str());
ofs1 << k; // Here I want to write that k to name3 file in ordinary text mode.
ifs1.close();
ofs1.close();
// Now I hope both name1 and name2 contain 5.
keep_window_open();
return 0;
}
Now what the ofs.write(as_bytes(j), sizeof(int));
or ifs.read(as_bytes(k), sizeof(int));
exactly means?
My question is why, in practice, the file name1
contains digit 5 and its size is 1 byte. The name2
contains some character/sign like []
and its size is 4 bytes and name3
contains digit 0 and its size is 1 byte?
I'll completely appreciate your responses.
Please don't extent the issue by giving extra info and only think around this problem. I want to just understand it. (My machine is Windows 7 32-bit. My compiler is MVS 2012. And if any more info is needed just tell me.)
回答1:
write and read
write
and read
methods are used for i/o operations with binary files.
They has the following prototypes:
write(memory_block, size);
read(memory_block, size);
The write
writes size
bytes from memory_block
to associated file.
The read
reads size
bytes from associated file and writes it to a memory_block
For example, in your case,
ofs.write(as_bytes(j), sizeof(int));
writes bytes of j
number into a bynary file named name2
.
You can see more about input and output with files here.
Why you havn't number five in name2 five
You write the bytes of j
variable to name2
file in binary i/o mode. Any i/o operation is performed independently of any format considerations in this mode. It don't add carriage return after written data. This means that you can't read the name2
file and see the five number there.
Why you have a zero number in name3 file
The reason is because of typo :)
First look at the lines
ifstream ifs(name1.c_str()); // Here I want to read from the ordinary text file (name1).
ifs >> j; // Now j equals to 5 because name1 contains digit 5.
ifs.close();
And then look at the lines
ifstream ifs1(name2.c_str(), ios::binary); // Here I want to read from that binary file (name2).
ifs.read(as_bytes(k), sizeof(int)); // Here I hope k becomes 5.
You are trying to read bytes from already closed file stream object. Any operation with such objects ends up with error. You can check it out in this way:
assert(!ifs.read(as_bytes(k), sizeof(int)));
It is possible because read
returns a mutable reference to ifs
and ifs
is convertible to boolean value.
Because of all stuff above in this section, the value of variable k
stay unchanged.
You can't read from closed file, you can't change the k
value. Because of this the old
value of k
is written to the name3
file.
Working example
#include <assert.h>
#include <fstream>
#include <string>
using namespace std;
typedef char byte;
template<typename T>
byte* as_bytes(T* ptr) {
return reinterpret_cast<byte*>(ptr);
}
int main()
{
string
name1 = "first.txt",
name2 = "second.bin",
name3 = "third.txt";
int j = 0, k = 0;
// Here I want to read from the ordinary text file (name1).
ifstream ifs(name1.c_str());
ifs >> j;
// Now j equals to 5 because name1 contains digit 5.
assert(j == 5);
ifs.close();
ofstream ofs(name2.c_str(), ios::binary);
// Here I want to write that j to name2 file in binary mode.
ofs.write(as_bytes(&j), sizeof(int));
ofs.close();
// Here I want to read from that binary file (name2).
ifstream ifs1(name2.c_str(), ios::binary);
// Here I hope k becomes 5.
ifs1.read(as_bytes(&k), sizeof(int));
ofstream ofs1(name3.c_str());
// Here I want to write that k to name3 file in ordinary text mode.
ofs1 << k;
ifs1.close();
ofs1.close();
}
回答2:
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
来源:https://stackoverflow.com/questions/20772946/how-to-convert-a-text-file-into-binary-and-vice-versa