visual-studio - 关于c++文件流读取和写入string类出错的问题,求解答
巴扎黑
巴扎黑 2017-04-17 14:23:23
0
3
579

在用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;
}

以下是第一次运行情况,是正确的

接下来关闭后重新运行再次输入,会出现错误:

初学者不太明白这是为什么,第一次提问,求大神指点,先谢谢各位啦!

巴扎黑
巴扎黑

全部回覆(3)
刘奇

首先要明白,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來實現的。

小葫芦

1、string的實現在各庫中有所不同,但是在同一庫中相同一點是,無論你的string裡放多長的字符串,它的sizeof()都是固定的,字符串所佔的空間是從堆中動態分配的,與sizeof()無關。
so, write 和 read 的第二個參數傳的都是錯誤的。
2.第二運行出錯,是在析構string時出的錯
3、read 那裡如果你換一個buffer 來接收,應該是沒有數據的, 你可以試試, 也就是說, 你的read出來的a其實還是原來的a

伊谢尔伦

取得string的C風格的位址要c_str()成員才行,長度是string.len

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!