【发布时间】:2014-05-25 05:09:39
【问题描述】:
需要格式化,编辑需要一些时间。
【问题讨论】:
-
人们在问题中编辑(损坏)代码建议使得其他人几乎不可能理解现有答案和 cmets,或者将问题描述与代码匹配。人们应该在他们的答案中发布更正的代码,或者如果 user2806369 想要 - 附加“工作版本”作为编辑问题。
需要格式化,编辑需要一些时间。
【问题讨论】:
该文件只有 16 个字节,因为当您将 a.p 写入文件时,您正在写入一个指向内存中字符串的四字节指针值——您并没有写出字符串数据本身。
它看起来起作用的原因是您立即将相同的指针值读回同一进程中的另一个指针变量,因此当您读取 bp 指向的内存时,它与 bp 指向的内存相同ap,即以NUL结尾的字符串文本。
如果您创建了第二个程序,它只是读取文件,而不声明字符串文本,您应该会遇到错误,或者至少看不到文本。
int main()
{
string filepath("C:\\Users\\Chitra\\Desktop\\New folder\\Project1\\Project1\\test.txt");
fstream fin(filepath,ios::in|ios::binary);
struct block
{
int value;
int size;
const char* p;
int some;
};
block b;
fin.read((char*)&b, sizeof(b));
fin.seekg(0, ios::end);
cout << "file size " << fin.tellg();
fin.close();
cout << "\n size b " << sizeof(b);
cout << "\n"<<b.value << " " << b.size << " " << b.p << " " << b.some;
getchar();
return 0;
}
【讨论】:
struct block;我建议您尝试编译和运行类似于上面所附程序的程序。 (在编辑中)
fout.write(str.c_str(), str.length()+1)另外一个常用的选项是先写一个长度,再写字符串数据,可以终止也可以不终止:size_t s = str.length();fout.write(&s, sizeof(s));fout.write(str.c_str(), s);
operator <<(ostream&),它首先写入 NUL 终止的数据或长度。如果你不能添加成员函数,你可以写一个 operator <<(ostream& , struct block) 来做同样的事情。
正如 Sam Mikes 所说,block.p 是指针,你只保存它的值(指针的值是它指向的内存的地址)并且因为 ap 仍然指向它在内存中,所以内存不会改变 add delete a; 喜欢下面的代码,看看不同
*注意:sizeof a 和 b 和 block 是一样的,你可以用sizeof(a) or sizeof(b) or sizeof(block) 代替
#include <string>
#include<iostream>
#include <fstream>
using namespace std;
int main(){
string text("C:\\Users\\Chitra\\Desktop\\Capture.JPG");
string filepath("C:\\Users\\Chitra\\Desktop\\New folder\\Project1\\Project1\\test.txt");
fstream fout(filepath,ios::out|ios::binary);
fstream fin(filepath,ios::in|ios::binary);
struct block {
int value;
int size;
const char* p;
int some;
};
block a;
a.value =1457745;
a.size=text.length();
a.p=text.c_str();
a. some=97877;
fout.write((char*)&a,sizeof(a));
fout.close();
delete a.p;
block b;
fin.read((char*)&b,sizeof(b));
fin.seekg(0,ios::end);
cout<<"file size "<<fin.tellg();
fin.close();
cout<<"\nsize a "<<sizeof(a)<<" size b "<<sizeof(b)<<" size block "<<sizeof (block);
cout<<"\n"<<b.value<<" "<<b.size<<" "<<b.p<<" "<<b.some;
getchar();
return 0;
}
【讨论】:
你不能只是这样做......
fout.write(pointer, bytes);
...对于pointer 和byte 的任何 值,因为数据不存在于连续内存中。您必须分别写入不带指针的block 中嵌入的数据和指向的字符串数据。如果将指针移到结构的末尾,那是最简单的,然后写:
struct block
{
int value;
int some;
int size;
const char* p;
};
fout.write((char*)&a, sizeof a - sizeof a.p);
// could also "offsetof(block, p)" for size - possibly more fragile
fout.write(a.p, a.size);
然后,读取数据:
block b;
fin.read((char*)&b, sizeof b - sizeof b.p);
b.p = new char[b.size + 1];
fin.read(b.p, b.size);
b.p[b.size + 1] = '\0'; // guarantee NUL termination
稍后您需要delete[] b.p; 来释放new[] 返回的内存。或者,您可以使用另一个string:
block b;
fin.read((char*)&b, sizeof b - sizeof b.p);
std::string b_string(b.size, ' '); // initially b.size spaces
fin.read(&b_string[0], b.size); // overwrite with data from the file...
使用std::string,在调用析构函数时会自动进行解除分配。
(实际上最好使用带有std::fstreams 的C++ 序列化库,例如boost's here。)
【讨论】: