首页 > 解决方案 > ifstream 在行尾读取额外字符 (CR 13 LF 10)

问题描述

我目前正在阅读一个文本文件,其中换行符占用 2 个字节,因为它将换行符写为 CRLF 而不仅仅是 LF。

std::fstream fileReader = std::fstream(_filename, std::ios::in);

// READ THE SIZE OF THE FILE:
fileReader.seekg(0, fileReader.end); // set reader position to the end
std::streamsize fileSize = fileReader.tellg(); // get reader position
fileReader.seekg(0, fileReader.beg); // set reader position to the start

// SET UP THE BUFFER:
std::vector<char> buffer; buffer.resize(fileSize, '\0');
buffer.back() = '\0';

// READ:
fileReader.read(buffer.data(), fileSize);

问题是,“fileSize”实际上是文件的大小,而不是文件中非 CF 字符的数量——这是它所期望的。

有没有办法自动获取该号码?

否则,我想二进制模式是唯一的选择——尽管它会非常令人失望,因为我期待在不使用二进制模式时进行正确的自动格式化。此外,.read 函数失败(fileReader 的失败位为真)

标签: c++ifstream

解决方案


有没有办法自动获取该号码?

这不能自动完成,因为文件系统不存储文件中的行尾数。任何方法都需要通过文件检查每个字符。幸运的是,可以利用std::fstream该类来处理大部分繁重的工作。生成的功能与您当前拥有的功能惊人地相似。您只需要获取读取的字符数。

// Gets the number of characters in `textfile` accounting for CR-LF being read as one character.
// The stream will be reset to the beginning when this function returns.
std::streamsize char_count(std::fstream & textfile)
{
    std::streamsize count = textfile.gcount();

    // Get an upper bound on the size.
    textfile.clear();
    textfile.seekg(0, textfile.end); // set reader position to the end
    std::streamsize fileSize = textfile.tellg(); // get reader position

    if ( textfile  &&  fileSize != -1 )
    {
        // Read the text.
        std::vector<char> buffer(fileSize);
        textfile.seekg(0, textfile.beg); // set reader position to the start
        textfile.read(buffer.data(), fileSize);

        // Get the count of characters read.
        count = textfile.gcount();
    }

    // Reset the stream.
    textfile.clear(); // Because over-reading would set some flags.
    textfile.seekg(0, textfile.beg);
    textfile.clear(); // In case the seek failed. We did promise to reset the stream.

    return count;
}

这样做似乎很浪费,一旦你有字符数就重复阅读,但由于你不会告诉我们你的真正问题,这可能会让你朝着更好的方向前进。


推荐阅读