tellg() 失败的可能原因?

发布于 2024-08-19 02:17:37 字数 2363 浏览 11 评论 0原文

ifstream::tellg() 对于某个文件返回 -13。

基本上,我编写了一个实用程序来分析一些源代码;我按字母顺序打开所有文件,从“Apple.cpp”开始,它工作得很好。但是当它到达“Conversion.cpp”时,总是在同一个文件上,成功读取一行后,tellg() 返回-13。

有问题的代码是:

for (int i = 0; i < files.size(); ++i) { /* For each .cpp and .h file */
   TextIFile f(files[i]);
   while (!f.AtEof()) // When it gets to conversion.cpp (not on the others)
                      // first is always successful, second always fails
      lines.push_back(f.ReadLine());

AtEof 的代码是:

    bool AtEof() {
        if (mFile.tellg() < 0)
            FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
        if (mFile.tellg() >= GetSize())
            return true;

        return false;
    }

成功读取 Conversion.cpp 的第一行后,它总是崩溃并显示 DEBUG -tellg(): -13

这是整个 TextIFile 类(由我编写,可能存在错误):

class TextIFile
{
public:
    TextIFile(const string& path) : mPath(path), mSize(0) {
        mFile.open(path.c_str(), std::ios::in);

        if (!mFile.is_open())
            FATAL(format("Cannot open %s: %s") % path.c_str() % strerror(errno));
    }

    string GetPath() const { return mPath; }
    size_t GetSize() { if (mSize) return mSize; const size_t current_position = mFile.tellg(); mFile.seekg(0, std::ios::end); mSize = mFile.tellg(); mFile.seekg(current_position); return mSize; }

    bool AtEof() {
        if (mFile.tellg() < 0)
            FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
        if (mFile.tellg() >= GetSize())
            return true;

        return false;
    }

    string ReadLine() {
        string ret;
        getline(mFile, ret);
        CheckErrors();
        return ret;
    }

    string ReadWhole() {
        string ret((std::istreambuf_iterator<char>(mFile)), std::istreambuf_iterator<char>());
        CheckErrors();
        return ret;
    }

private:
    void CheckErrors() {
        if (!mFile.good())
            FATAL(format("An error has occured while performing an I/O operation on %s") % mPath);
    }

    const string mPath;
    ifstream mFile;
    size_t mSize;
};

平台是 Visual Studio,32 位,Windows。

编辑:适用于 Linux。

编辑:我找到了原因:行结尾。 Conversion 和 Guid 等都用 \n 而不是 \r\n。我用 \r\n 保存它们并且它有效。不过,这不应该发生,不是吗?

ifstream::tellg() is returning -13 for a certain file.

Basically, I wrote a utility that analyzes some source code; I open all files alphabetically, I start with "Apple.cpp" and it works perfectly.. But when it gets to "Conversion.cpp", always on the same file, after reading one line successfully tellg() returns -13.

The code in question is:

for (int i = 0; i < files.size(); ++i) { /* For each .cpp and .h file */
   TextIFile f(files[i]);
   while (!f.AtEof()) // When it gets to conversion.cpp (not on the others)
                      // first is always successful, second always fails
      lines.push_back(f.ReadLine());

The code for AtEof is:

    bool AtEof() {
        if (mFile.tellg() < 0)
            FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
        if (mFile.tellg() >= GetSize())
            return true;

        return false;
    }

After it reads successfully the first line of Conversion.cpp, it always crashes with DEBUG - tellg(): -13.

This is the whole TextIFile class (wrote by me, the error may be there):

class TextIFile
{
public:
    TextIFile(const string& path) : mPath(path), mSize(0) {
        mFile.open(path.c_str(), std::ios::in);

        if (!mFile.is_open())
            FATAL(format("Cannot open %s: %s") % path.c_str() % strerror(errno));
    }

    string GetPath() const { return mPath; }
    size_t GetSize() { if (mSize) return mSize; const size_t current_position = mFile.tellg(); mFile.seekg(0, std::ios::end); mSize = mFile.tellg(); mFile.seekg(current_position); return mSize; }

    bool AtEof() {
        if (mFile.tellg() < 0)
            FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
        if (mFile.tellg() >= GetSize())
            return true;

        return false;
    }

    string ReadLine() {
        string ret;
        getline(mFile, ret);
        CheckErrors();
        return ret;
    }

    string ReadWhole() {
        string ret((std::istreambuf_iterator<char>(mFile)), std::istreambuf_iterator<char>());
        CheckErrors();
        return ret;
    }

private:
    void CheckErrors() {
        if (!mFile.good())
            FATAL(format("An error has occured while performing an I/O operation on %s") % mPath);
    }

    const string mPath;
    ifstream mFile;
    size_t mSize;
};

Platform is Visual Studio, 32 bit, Windows.

Edit: Works on Linux.

Edit: I found the cause: line endings. Both Conversion and Guid and others had \n instead of \r\n. I saved them with \r\n instead and it worked. Still, this is not supposed to happen is it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风流物 2024-08-26 02:17:37

如果不确切知道 Conversion.cpp 中的内容,就很难猜测。但是,标准并未定义将 < 与流位置一起使用。在格式化之前,您可能需要考虑显式转换为正确的整数类型;我不知道 FATALformat() 期望执行什么格式,也不知道 % 运算符如何重载。流位置不必以可预测的方式映射到整数,如果文件不是以二进制模式打开的话当然不需要。

您可能需要考虑 AtEof() 的替代实现。说这样的话:

bool AtEof()
{
    return mFile.peek() == ifstream::traits_type::eof();
}

It's difficult to guess without knowing exactly what's in Conversion.cpp. However, using < with stream positions is not defined by the standard. You might want to consider an explicit cast to the correct integer type before formatting it; I don't know what formatting FATAL and format() expect to perform or how the % operator is overloaded. Stream positions don't have to map in a predicatable way to integers, certainly not if the file isn't opened in binary mode.

You might want to consider an alternative implementation for AtEof(). Say something like:

bool AtEof()
{
    return mFile.peek() == ifstream::traits_type::eof();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文