Ifstream读取失败时达到特定大小(与文件大小无关)

MyU*_*358 2 c++ ifstream

我试图读取文件,但我意识到它将失败,因为即使文件比我要读取的文件大得多,我也会尝试读取过多的数据。

该文件为120 MB,我的ifstream失败时为12967字节(即使它在12801时开始表现异常)。

这是说明我的问题的代码:

#include <fstream>
#include <iostream>
#include <Windows.h>

using std::ifstream;
using std::cout;

#define CORRECT_SIZE 12800
#define CORRECT_BUT_WIERD 12966
#define INCORRECT_SIZE 12967

bool check_error_bits(ifstream* f);

int main()
{
    ifstream myFile("myfile.txt");
    char c[CORRECT_SIZE];
    char c2[CORRECT_BUT_WIERD];
    char c3[INCORRECT_SIZE];

    /*
     * TEST A (works fine)
    */
    myFile.seekg(0, std::ios_base::beg);
    myFile.read(c, CORRECT_SIZE);
    check_error_bits(&myFile);
    cout << myFile.tellg() << std::endl; // Here, tellg() returns 12800

    /*
     * TEST B (works too, but acts wierd)
     */
    myFile.seekg(0, std::ios_base::beg);
    myFile.read(c2, CORRECT_BUT_WIERD);
    check_error_bits(&myFile);
    cout << myFile.tellg() << std::endl; // Here, tellg() returns 16896

    /*
     * TEST C (FAIL)
    */
    myFile.seekg(0, std::ios_base::beg);
    myFile.read(c3, INCORRECT_SIZE);
    check_error_bits(&myFile);
    cout << myFile.tellg() << std::endl; // Here, tellg() returns -1

    system("pause");
}

bool check_error_bits(ifstream* f)
{
    bool stop = false;

    if (f->eof())
    {
        char msg[500];
        strerror_s(msg, errno);
        cout << "1: " << msg << std::endl;
    }

    if (f->fail())
    {
        char msg[500];
        strerror_s(msg, errno);
        cout << "2: " << msg << std::endl;
        stop = true;
    }

    if (f->bad())
    {
        char msg[500];
        strerror_s(msg, errno);
        cout << "3: " << msg << std::endl;
        stop = true;
    }

    return stop;
}
Run Code Online (Sandbox Code Playgroud)

尝试读取少于12800个字节的方法效果很好。从128001到12966,它可以工作(尽管我还没有检查数据是否正确),但是tellg()返回的是无意义的。12966之后,读取完全失败。

该程序的控制台输出为:

12800
16896
1: No error
2: No error
-1
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激!

pas*_*qui 5

在Windows环境和文本文件中,将值26 = 0x1A = ^ Z的字符作为“ end fo文件”。

因此,如果文件未以二进制形式打开,则即使文件较大也可能会收到意外的eof。

参见维基百科“文件结尾”(https://en.wikipedia.org/wiki/文件结尾):

在Microsoft的DOS和Windows(以及CP / M和许多DEC操作系统)中,从终端读取将永远不会产生EOF。相反,程序会识别出源是终端(或其他“字符设备”),并将给定的保留字符或序列解释为文件结束指示符。最常见的是ASCII Control-Z,代码26。