【问题标题】:Check if the string is of type T in C++11在 C++11 中检查字符串是否为 T 类型
【发布时间】:2012-09-28 03:54:29
【问题描述】:

是否有标准库函数来检查字符串 S 是否属于 T 类型,因此可以转换为 T 类型的变量?

我知道有一个 istringstream STL 类,它可以使用 operator>> 用从字符串转换的值填充 T 类型的变量。但是,如果字符串内容不是T类型的格式,则会被无意义填充。

【问题讨论】:

  • it will be filled with nonesense if the string content did not have the format of type T. 那是因为它没有初始化。
  • 字符串没有类型。你能做的最好的就是猜测,使用类似boost::lexical_cast

标签: c++ string types


【解决方案1】:

正如@Cameron 评论的那样,你能做的最好的就是尝试并失败:

#include <string>
#include <sstream>
#include <boost/optional.hpp>

template <typename T>
boost::optional<T> convert(std::string const & s)
{
    T x;
    std::istringstream iss(s);
    if (iss >> x >> std::ws && iss.get() == EOF) { return x; }
    return boost::none;
}

或者,没有提升:

template <typename T>
bool convert(std::string const & s, T & x)
{
    std::istringstream iss(s);
    return iss >> x >> std::ws && iss.get() == EOF;
}

用法:

  • 第一版:

    if (auto x = convert<int>(s))
    {
        std::cout << "Read value: " << x.get() << std::endl;
    }
    else
    {
        std::cout << "Invalid string\n";
    }
    
  • 第二版:

    {
        int x;
        if (convert<int>(s, x))
        {
            std::cout << "Read value: " << x << std::endl;
        }
        else
        {
            std::cout << "Invalid string\n";
        }
    }
    

请注意,boost::lexical_cast 基本上是一个更聪明的版本,它声称非常有效(可能比我们在这里所做的无条件使用 iostreams 更有效)。

【讨论】:

  • 简洁正确。我怀疑 OP 会在没有进一步解释的情况下理解(尤其是后者,如果您不仔细阅读,这似乎......太微不足道了:))
  • 这将成功,将“123abc”之类的字符串转换为int,这通常不是人们所期望的。
【解决方案2】:

没有标准库函数。要查看是否成功,您应该检查来自operator&gt;&gt;的返回:

std::istringstream iss(mystring);

// if you want trailing whitespace to be invalid, remove std::ws
if((iss >> myT >> std::ws) && iss.eof())
{
   // success
}
else
{
   // failed
}

【讨论】:

  • 我认为如果流没问题,流会转换为“真”。
  • 这将在带有尾随空格的字符串上失败(可能是 OP 想要的)。
  • @jrok:是的,在大多数情况下,您可能希望丢弃空格(已编辑)。
猜你喜欢
  • 1970-01-01
  • 2020-10-17
  • 2016-09-04
  • 2013-12-15
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
相关资源
最近更新 更多