【问题标题】:Possible reasons for tellg() failing?tellg() 失败的可能原因?
【发布时间】:2010-01-22 23:04:43
【问题描述】:

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 保存了它们,它起作用了。不过,这不应该发生吧?

【问题讨论】:

  • iostreams sux。使用其他东西:P
  • 总是打开这个文件还是第N个文件? IOW,如果您重命名了conversion.cpp,使其落在排序列表中的其他位置,它仍然是失败的文件吗?
  • 只是出于兴趣,Conversion.cpp 有多长,第一行读了多长时间?
  • @Duck:重命名,它现在用 Guid.h 失败了。在列表中(中间有大约 10 个文件)
  • @Charles Bailey:这是 Conversion.cpp - codepad.org/yfHwXD1h 。第一行是 /****...****/。项目中的每个文件都以该行开头。

标签: c++ file fstream ifstream line-endings


【解决方案1】:

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

您可能需要考虑为AtEof() 提供替代实现。像这样说:

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

【讨论】:

  • format() 是 boost::format.. 用 VS 调试器查看 mFile _Fpos 是 -13 ...
猜你喜欢
  • 1970-01-01
  • 2012-02-24
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 2019-06-23
相关资源
最近更新 更多