程序写得很好,但没有阅读

时间:2016-07-17 15:42:50

标签: c++

#include<fstream>
#include<iostream>
using namespace std;
int main()
{
    int i = 20;

    fstream fs("someFile.dat", ios::out | ios::binary | ios::in);
    if(!fs)
    {
        cout << "FILE COULD NOT BE OPENED" << endl;
    }

    fs.write(reinterpret_cast<const char*>(&i),sizeof(int));
    i = 0;
    fs.read(reinterpret_cast<char*>(&i),sizeof(int));
    cout << i << endl;  // shows 0
}

最后一个cout中的'i'应显示20但显示为0.

1 个答案:

答案 0 :(得分:3)

写入文件后,您就在文件的末尾。

您可以使用tellg或“告诉获取”来解决这个问题:

std::cout << "Position in file is: " << fs.tellg() << std::endl;

这将告诉您文件开头的文件内的字节偏移量。在从文件中读取字节之前,首先需要在文件中寻找适当的位置。为此,我们可以使用seekg或“寻求获取”。

fs.seekg(0);

这将寻找文件的开头(文件开头的字节偏移量为0),因此您应该能够正确读取文件。

对于您的示例,seekgseekp应该是tellgtellp相同,但理想情况下应使用以“g”结尾的成员函数(输入流的“get”)和输出流的“p”(“put”)结尾的函数。

修改

@Borgleader在评论中提出了一个很好的观点,对于更复杂的例子,你可能不知道读取是否失败。为此,您可以检查失败位:

if (fs.fail()) {   
    // you can check more specific error codes with std::ios_base::iostate
    // fs.fail() will evaluate to 0 if no error, or false, otherwise it has an error
    std::cout << "Failed to read from file" << std::endl;
}

<强>更新

要分析iostate标志,您可以使用fstream成员函数goodeoffailbad。检查原始示例的fstream的iostate的快速示例如下:

#include <fstream>
#include <iostream>

int main()
{
    int i = 20;
    std::fstream fs("someFile.dat", std::ios::out | std::ios::binary | std::ios::in);
    fs.write(reinterpret_cast<const char*>(&i), sizeof(int));
    i = 0;
    fs.read(reinterpret_cast<char*>(&i), sizeof(int));
    // you can check other settings via the ios::fail() member function
    if (fs.good()) {            // checks goodbit
        std::cout << "File is normal, no errors\n";
    }
    if (fs.eof()) {            // checks end of file
        std::cout << "End of file\n";
    }
    if (fs.fail()) {            // checks failbit or badbit
        std::cout << "Failed to read, failbit\n";
    }
    if (fs.bad()) {             // checks the badbit
        std::cout << "Failed to read, badbit\n";
    }
}

这在运行时产生以下输出:

End of file
Failed to read, failbit

总的来说,经常检查读取是否失败就足够了,除非您需要进一步优化逻辑。