【问题标题】:Input Redirection reading integers and char C++输入重定向读取整数和字符 C++
【发布时间】:2018-08-05 09:07:21
【问题描述】:

感谢您抽出宝贵时间阅读本文!

我在通过输入重定向解析文件时遇到问题,并且在读取整数和字符时遇到问题。

如果不使用 getline(),您如何读取文件中的整数、字符和任意数量的空格? (我知道 >> 运算符可以跳过空格,但在遇到字符时会失败)

谢谢!

【问题讨论】:

  • 显示您目前编写的代码。
  • “但击中字符失败” ??

标签: c++ input integer character io-redirection


【解决方案1】:

您需要意识到的第一件事是,从根本上说,您的文件中没有“整数”之类的东西。您的文件不包含输入数据:它包含 字节

现在,由于 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”提取到值为123int 中,并将"abc" 提取到另一个字符串中。

但是,如果您需要更复杂的解析,您可以回到最初的产品,并得出我的答案的结论:阅读所有内容并按照您认为合适的方式逐字节解析它。为了解决这个问题,有从 C 标准库继承的 sscanfspooky incantations from Boost;或者您可以编写自己的算法。

以上内容适用于任何兼容的输入流,无论是std::ifstreamstd::istringstream,还是名为std::cin 的旧式现成std::istream 实例(我猜你就是这样接受的)数据,鉴于您提到输入重定向:shell 脚本?)。

【讨论】:

    猜你喜欢
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-01
    • 2021-12-24
    • 2014-03-28
    • 2012-07-21
    相关资源
    最近更新 更多