首頁  >  問答  >  主體

visual-studio - 关于c++文件流读取和写入string类出错的问题,求解答

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

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

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

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

巴扎黑巴扎黑2765 天前622

全部回覆(3)我來回復

  • 怪我咯

    怪我咯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來實現的。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 14:25:23

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

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 14:25:23

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

    回覆
    0
  • 取消回覆