感谢您花时间阅读本文!
我在使用输入重定向解析文件时遇到问题,而我在阅读整数和字符时遇到问题。
不使用getline(),你如何在文件中读取包括整数,字符和任何数量的空格? (我知道>>运算符可以跳过空格但在遇到字符时失败)
谢谢!
答案 0 :(得分:1)
你需要意识到的第一件事是,从根本上说,没有像"整数和#34;在你的文件中。您的文件不包含类型化数据:它包含 bytes 。
现在,由于C ++不支持任何文本编码,为了我们的目的,我们可以考虑相当于"字符"的字节。 (实际上,你可能会在你的代码之上添加类似UTF-8支持库的东西,此时#34;字符"会带来全新的含义。但我们会节省那个讨论的另一天。)
最基本的,我们可以提取一堆字节。让我们一次说50个:
std::ifstream ifs("filename.dat");
static constexpr const size_t CHUNK_SIZE = 50;
char buf[CHUNK_SIZE];
while (ifs.read(buf, CHUNK_SIZE)) {
const size_t num_extracted = ifs.gcount();
parseData(buf, num_extracted);
}
函数parseData
将以您认为合适的方式检查这些字节。
对于许多文本文件,这是不必要的艰巨。因此,正如您所发现的,C ++标准库的IOStream部分为我们提供了一些快捷方式。例如,std::getline
将读取字节直到分隔符,而不是读取某个数量的字节。
使用这个,我们可以逐行阅读"" - 假设"线"是一个由\n
(或\r\n
终止的字节序列,如果您的平台执行行结束转换,并且您还没有将流转换为二进制模式):
std::ifstream ifs("filename.dat");
static constexpr const size_t CHUNK_SIZE = 50;
std::string line;
while (std::getline(ifs, line)) {
parseLine(line);
}
作为\n
的第三个参数,您可以提供一些其他分隔符,而不是std::getline
。
它提供的另一个工具是operator<<
,它将挑选令牌(由空格分隔的字节序列)并尝试&#34;词法转换&#34;他们;也就是说,它会尝试将友好的人类ASCII文本解释为C ++数据。因此,如果您的输入是&#34; 123 abc&#34;,您可以提取&#34; 123&#34;进入值为int
的{{1}},将123
改为另一个字符串。
如果你需要更复杂的解析,你可以回到最初的产品,并回答我的答案:阅读所有内容并按照你认为合适的方式逐字节解析。为了帮助解决这个问题,我的sscanf
继承自C标准库,或spooky incantations from Boost;或者你可以编写自己的算法。
以上适用于任何兼容的输入流,无论是"abc"
,std::ifstream
,还是名为std::istringstream
的旧的现成std::istream
实例(其中我想你是如何接受数据的,你提到输入重定向:shell脚本?)。