在用vs2015编程学习文件流时出现问题,就是以二进制app方式写入和读取string类型时出现问题,只有第一次输入可以显示,之后增加字符串在此读取输出就会报错,求大神指点
以下是代码:
#include <string>
#include <iostream>
#include<iomanip>
#include<fstream>
using namespace std;
int main()
{
ofstream outfile("try.dat", ios::app | ios::binary);
string a;
cin >> a;
outfile.write((char*)&a, sizeof(a));
ifstream infile("try.dat", ios::in | ios::binary);
if (!infile)
{
cout << "weew";
}
infile.read((char*)&a, sizeof(a));
outfile.close();
infile.close();
cout << a << endl;
return 0;
}
以下是第一次运行情况,是正确的
接下来关闭后重新运行再次输入,会出现错误:
初学者不太明白这是为什么,第一次提问,求大神指点,先谢谢各位啦!
首先要明白,
string
不是一个简单的数组类型,它是一个类,拥有自己的成员变量和成员函数而a是string类型的,故a是一个复杂的对象,执行
&a
来取得a的地址并没有什么意义,将其强转为char*
类型更是说不通,把一个string*
强转为char*
,是一个指针到指针的转换,指针的值并未改变,只是告诉了编译器一声:同样是这个指针,现在别把我当string*
看待了,要当我是char*
(这有卵用啊……)感觉题主的本意是想把一个string转化为传统的C字符串(就是一个char数组),那么请使用
a.c_str()
来获取真正的char*
(这个是string内部构造好的,而非像题主那样胡乱强转出来的);此外,使用a.len()
可以获得这个字符串的长度。顺便一提,如果题主实在无法理解为什么
sizeof(a)
不是字符串的长度,可以看看如下的仿例(我生造出来的):可以看到,
sizeof(a)
永远都是len_string的长度
+str的长度
=8字节
,并不会变成20字节,所谓的字符串长度动态变化,是通过new
以及一个记录长度的变量len_string
来实现的。1、string的实现在各库中有所不同,但是在同一库中相同一点是,无论你的string里放多长的字符串,它的sizeof()都是固定的,字符串所占的空间是从堆中动态分配的,与sizeof()无关。
so, write 和 read 的第二个参数传的都是错误的。
2、第二运行出错,是在析构string时出的错
3、read 那里如果你换一个buffer 来接收,应该是没有数据的, 你可以试试, 也就是说, 你的read出来的a实际上还是原来的a
获取string的C风格的地址要c_str()成员才行,长度是string.len