c++ - 在 C++ 中解析整个(开始到结束)字符串,包括所有空格

标签 c++ parsing

我正在寻找一种在 C++ 中通用解析整个字符串的方法。我的意思是在解析中使用了整个字符串,否则它就是一个错误。这意味着天真的 operator >>为大多数类型分隔空白的行为不是我想要的(尽管如果解决方案涉及它,我会非常高兴)。一些例子:

// Parse a whole value, throwing an exception if there's a parse error
void parse_into<typename T>(const char* input, T& result);

double value = 0;
parse_into("12.5", value);  // #1: Success
parse_into("ABC", value);  // #2: Fail
parse_into("12.5 abc", value);  //#3: Fail

std::string str_value;
parse_into("ABC", str_value);  // #4: Success
parse_into("ABC ABC", str_value);  // #5: Success; str_value == "ABC ABC"
parse_into("ABC  ABC", str_value);  // #6: Success; str_value == "ABC  ABC'

我相信我想要的围绕 stringstreamoperator >> .我可以通过检查 stringstream是空的。但是,我想不通的是一种通用的方法来允许可以从任何字符串构造的类型,例如 std::string .可能是涉及可以从 const char* 构造的类型的 SIFNAE 重载。 ?

我对最终界面没有特别的形式要求;我想要的是让它做任何给定类型的“正确的事情”。对于上下文,这是一个命令行参数解析库。该库处理检测单词边界,所以我知道 parse_into 的输入是我要阅读的整个单词。

最佳答案

对于 double这可以通过 std::stod 来实现在第一次将您的输入读取为 std::string 之后.

std::optional<double> parse(std::string const& str) {
  std::size_t num = 0;
  try {
    auto const res = std::stod(str,&num);
    if (num < str.size()) return std::nullopt;
    return res;
  } catch (...) {
    return std::nullopt;
  }
}

您可以为不同的类型创建重载(例如,使用传入的值)。我正在使用 std::optional 在这里,但你也可以throw或使用任何其他方式传达错误。

例如:
bool parse(std::string const& str, double& out);
bool parse(std::string const& str, std::uint32_t& out);
bool parse(std::string const& str, std::string& out); // always succeeds
// ...

编辑 : 一个更通用的接口(interface),允许传递任何类型的 stoXYZ功能:
  template <typename T>
  static void parse(std::string const& s, T (*fun)(std::string const&,std::size_t*,int), std::optional<T>& out) { /**/ }   
  template <typename T>
  static void parse(std::string const& s, T (*fun)(std::string const&,std::size_t*), std::optional<T>& out) { /**/ }

这需要一个指向函数的指针,但它也可能需要一个 std::function目的。存在这两个重载是因为 std::stoistd::stod有不同的参数列表(整数需要一个基数)。

关于c++ - 在 C++ 中解析整个(开始到结束)字符串,包括所有空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61806378/

相关文章:

python - 如何使用 BeautifulSoup 查找表中包含 <p> 元素的第一个 <td> ?

c# - 将一本字典转换成另一本字典的最佳方法是什么

c++ - 为什么快速排序会引发异常 “write access violation”

C++ 在公共(public)容器中存储子对象

c++ - 无法从 XXX** 转换为常量 XXX**

Python lxml XPath 语法错误 : invalid predicate

json - 最佳实践-Json解析中的String与InputStream(使用gson)

python - 从类似 JSON 的 blob 中解析出这个值的最 Pythonic 方法是什么?

c++ - 包含指向自身的 "implementation"和 "interface"指针的 C++ 类有什么用?

c++ - 纹理不工作