我正在寻找一种在 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'
我相信我想要的围绕
stringstream
和 operator >>
.我可以通过检查 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::stoi
和 std::stod
有不同的参数列表(整数需要一个基数)。
关于c++ - 在 C++ 中解析整个(开始到结束)字符串,包括所有空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61806378/