为什么C++的文件 I/O 在读取文本文件时忽略初始空行?我怎样才能让它不这样做?



我正在尝试使用我自己的自定义正则表达式和抽象语法树解析库"srl.h"(又名"字符串和正则表达式库"(为自己构建一种迷你编程语言,我发现自己似乎无法弄清楚。

问题是这样的:当我的自定义代码遇到错误时,它显然会抛出一条错误消息,并且此错误消息包含有关错误的信息,一位是引发错误的行号。

问题在于,C++似乎只是忽略不包含字符的行(即只是 CRLF 的行(的存在,直到它找到一行确实包含字符,之后它停止忽略空行并正确处理它们,从而给出所有抛出的错误不正确的行号, 它们都因相同的偏移量而不正确。

基本上,如果给定一个包含内容"(crlf((crlf(abc(crlf(def">

的文件,它将被读取为其内容是"abc(crlf(def",忽略初始新行,从而报告任何和所有抛出的错误的错误行号。

这是我用来获取文本文件文本的(编码混乱不一(函数的副本。如果你们中的一个人能告诉我这里发生了什么,那就太棒了。

template<class charT> inline std::pair<bool, std::basic_string<charT>> load_text_file(const std::wstring& file_path, const char delimiter = 'n') {

std::ifstream fs(file_path);

std::string _nl = srl::get_nlp_string<char>(srl::newline_policy);

if (fs.is_open()) {

std::string s;

char b[SRL_TEXT_FILE_MAX_CHARS_PER_LINE];

while (!fs.eof()) {

if (s.length() > 0)
s += _nl;

fs.getline(b, SRL_TEXT_FILE_MAX_CHARS_PER_LINE, delimiter);

s += std::string(b);
}

fs.close();

return std::pair<bool, std::basic_string<charT>>(true, srl::string_cast<char, charT>(s));
}
else
return std::pair<bool, std::basic_string<charT>>(false, std::basic_string<charT>());
}

std::ifstream::getline(( 不会将分隔符(在本例中为 ''(输入到字符串中,并且还会将其从流中刷新,这就是为什么文件中的所有换行符(包括前导换行符(在读取时都会被丢弃的原因。

程序似乎不会忽略其他行之间的换行符的原因是:

if (s.length() > 0)
s += _nl;

所有换行符实际上都来自这里,但这在一开始就不可能发生,因为字符串是空的。

这可以通过一个小型测试程序进行验证:

#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ifstream inFile{ "test.txt" }; //(crlf)(crlf)(abc)(crlf)(def) inside
char line[80]{};
int lineCount{ 0 };
std::string script;
while (inFile.peek() != EOF) {
inFile.getline(line, 80, 'n');
lineCount++;
script += line;
}
std::cout << "***Captured via getline()***" << std::endl;
std::cout << script << std::endl; //prints "abcdef"
std::cout << "***End***" << std::endl << std::endl;
std::cout << "Number of lines: " << lineCount; //result: 5, so leading /n processed
}

如果删除 if 条件,则程序只有:

s += _nl;

,将插入换行符而不是文件中丢弃的换行符,但只要 '' 是分隔符,std::ifstream::getline(( 将继续丢弃原始换行符。

最后,我建议使用

while (fs.peek() != EOF){};

而不是

while(fs){};while(!fs.eof()){};

如果你在测试程序中查看int lineCount的最终值,后两个给出6而不是5,因为它们最终会进行冗余迭代。

相关内容

  • 没有找到相关文章

最新更新