在用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;
}
以下是第一次运行情况,是正确的
接下来关闭后重新运行再次输入,会出现错误:
初学者不太明白这是为什么,第一次提问,求大神指点,先谢谢各位啦!
怪我咯2017-04-17 14:25:23
首先要明白,string
不是一個簡單的陣列類型,它是一個類,擁有自己的成員變數和成員函數
而a是string類型的,故a是一個複雜的對象,執行&a
來取得a的地址並沒有什麼意義,將其強轉為char*
類型更是說不通,把一個string*
強轉為char*
,是一個指針到指針的轉換,指針的值並未改變,只是告訴了編譯器一聲:同樣是這個指針,現在別把我當string*
看待了,要當我是char*
(這有卵用啊…)
感覺題主的本意是想把一個string轉換為傳統的C字串(就是一個char數組),那麼請使用a.c_str()
來獲取真正的char*
(這個是string內部構造好的,而非像題主那樣胡亂強轉出來的);此外,使用a.len()
可以得到這個字串的長度。
順便一提,如果題主實在無法理解為什麼sizeof(a)
不是字串的長度,可以看看如下的仿例(我生造出來的):
class myString{
private:
int len_string;
char *str;
public:
myString(char* s){
len_string=strlen(s);
str=new char[len_string];
strcpy(str,s);
}
int len(){return len_string;}
char* c_str(){return str;}
};
myString a="12345678901234567890";
可以看到,sizeof(a)
永遠都是len_string的长度
+str的长度
=8字节
,並不會變成20字節,所謂的字串長度動態變化,是透過new
以及一個記錄長度的變數len_string
來實現的。
高洛峰2017-04-17 14:25:23
1、string的實現在各庫中有所不同,但是在同一庫中相同一點是,無論你的string裡放多長的字符串,它的sizeof()都是固定的,字符串所佔的空間是從堆中動態分配的,與sizeof()無關。
so, write 和 read 的第二個參數傳的都是錯誤的。
2.第二運行出錯,是在析構string時出的錯
3、read 那裡如果你換一個buffer 來接收,應該是沒有數據的, 你可以試試, 也就是說, 你的read出來的a其實還是原來的a