您需要意识到的第一件事是,从根本上说,您的文件中没有“整数”之类的东西。您的文件不包含输入数据:它包含 字节。
现在,由于 C++ 不支持任何文本编码,为了我们的目的,我们可以考虑等效于“字符”的字节。 (实际上,您可能会在代码之上添加 UTF-8 支持库之类的东西,此时“字符”具有全新的含义。但我们将把这个讨论留到另一天。)
那么,最基本的,我们可以提取一堆字节。假设一次 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++ 标准库的 IOStreams 部分为我们提供了一些快捷方式。例如,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<<,它将挑选出令牌(由空格分隔的字节序列)并尝试“按词法转换”它们;也就是说,它会尝试将友好的人类 ASCII 文本解释为 C++ 数据。因此,如果您的输入是“123 abc”,您可以将“123”提取到值为123 的int 中,并将"abc" 提取到另一个字符串中。
但是,如果您需要更复杂的解析,您可以回到最初的产品,并得出我的答案的结论:阅读所有内容并按照您认为合适的方式逐字节解析它。为了解决这个问题,有从 C 标准库继承的 sscanf 或 spooky incantations from Boost;或者您可以编写自己的算法。
以上内容适用于任何兼容的输入流,无论是std::ifstream、std::istringstream,还是名为std::cin 的旧式现成std::istream 实例(我猜你就是这样接受的)数据,鉴于您提到输入重定向:shell 脚本?)。