簡體   English   中英

C ++文件處理讀取函數錯誤

[英]C++ file handling read function error

我無法找到為什么此功能無法正常運行:

e1是班級員工的對象:

class emp
{
    public: 
        int no;
        char name[30];

        void enter()
        {
            std::cout<<"\n enter no. and name";
            std::cin>>no;
            gets(name);
        }

        void disp()
        {
            std::cout<<"\n\tNo.\t\tName\n\t"<<no<<"\t\t"<<name;
        }
};

程序永遠不會進入if子句。

void modify(int a)
{
    f1.open("emp.txt", ios::ate | ios::nocreate);
    float pos;
    f1.seekg(0, ios::beg);
    while (!f1.eof())
    {
        f1.read((char*)&e1, sizeof(e1));
        if (e1.no == a) // if e1.no == the number to be modified
        {
            pos = f1.tellg();
            pos = pos - sizeof(e1)
            e1.enter(); // enter new e1 details, function declared in class
            f1.seekp(pos, ios::beg);
            f1.write((char*)&e1, sizeof(e1)); // overwrite prev rec.
            cout << "\n modified";
        }
    }
    f1.close();
}

你不能像這樣反序列化一個類。 從實例基指針覆蓋內存很可能會造成嚴重破壞並將您發送到Undefined Behavior域。 如果你想這樣閱讀,需要考慮目標內存布局(提示:除非你的課非常簡單,否則它很可能不起作用)。

例如,如果Employee類繼承自另一個類,則該類的第一個成員通常是指向虛擬表的指針。 如果你這樣讀,你將覆蓋vtable指針。 不好。

有可能像這樣讀取一個C結構,但只要它包含指針,它就差不多了,因為下次你讀時,指向內存甚至可能不是你的。

由於您使用的C ++可能包含字符串,向量等成員,因此這樣的序列化可以保證失敗,因為它們使用動態內存分配。


編輯

既然你發布了emp的定義,我想我知道發生了什么。 我假設emp.txt是由另一個進程(或手動)編寫的文件。

我寫了一小段代碼來說明為什么你會像讀取對象一樣有問題:

emp e;
std::cout << "sizeof(emp) = " << sizeof(emp) <<std::endl;
std::cout << "sizeof(emp::no) = " << sizeof(e.no) <<std::endl;
std::cout << "sizeof(emp::name) = " << sizeof(e.name) <<std::endl;

std::cout << "&e = " << &e <<std::endl;
std::cout << "&e.no = " << &e.no <<std::endl;
std::cout << "&e.name = " << &e.name <<std::endl;

這是我運行的輸出:

sizeof(emp) = 36
sizeof(emp::no) = 4
sizeof(emp::name) = 30
&e = 00BBFDF4
&e.no = 00BBFDF4
&e.name = 00BBFDF8

我們可以看到no在對象的開頭:好。 我們還可以看到name位於內存中( 00BBFDF8 - 00BBFDF4 == sizeof(emp.no) )。 但是,當我們認為它應該是34時,對象的大小是36。這是因為對齊。 我系統上的默認值是4。

我懷疑emp.txt中的數據包含2個額外的字節來處理內存對齊。 因此,通過使用sizeof(e1)讀取,您可以讀取2個額外字節。 然后你就在下一個整數的中間。 這顯然會破壞您在下次讀取時所期望的數據。

然后讀取名稱也有問題。 即使對齊和內存布局與您的程序完全相同,您的文本文件也需要根據sizeof(名稱)編寫,因此每個員工姓名必須用額外的字符(空格?)填充為固定大小( 30個字節)。 我懷疑輸入文件是這樣編寫的。

我建議您根據輸入文件而不是用於存儲數據的類來實現讀取邏輯。 此外,如果數據不是固定大小,那么編輯文件將很難。

你在fstream::open()的flags參數中缺少ios::binary :肯定你在這里做二進制I / O.

然而,其他注釋的所有注意事項仍然是正確的:您應該添加(應該添加,如果這不能解決問題)至少e1的定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM