0

我正在尝试编写一个函数,该函数将一个字符串作为输入参数,三个可以是不同类型的输出参数(至少是这样的想法)和一个作为分隔符的字符。

输入字符串由指定的字符分隔,并且该函数按顺序将每个以字符结尾的字段分配给每个输出参数(目前它处理输入字符串,例如"a;bb;ccc"并且仅限于三个输出参数,但这不是问题)。

例如,对于输入,例如10;200;3000Id get 10200以及3000分别用于第一个、第二个和第三个输出参数

输出参数必须是字符串或整数类型,但由于我对 C++(尤其是泛型编程)的了解有限,我在编写一个不关心这一点的泛型函数时遇到了麻烦。

我有以下代码:

template <typename T>
void parse_string (std::string &input, T &out1, T &out2, T &out3, const char delimiter)
{
    while (out3 == "")
    {
        std::string temp = input.substr(0, input.find(delimiter));
        input = input.substr(input.find(delimiter) +1);

        if (out1 == "") { out1 = temp;}
        else if (out2 == "") { out2 = temp;}
        else { out3 = temp;}
    }
}

它适用于字符串,但显然不适用于整数。

我怀疑我在检查参数是否为空的地方出错了(以及我不知道的其他部分)。

你能帮我改进一下吗?

此外,我欢迎任何关于改进逻辑本身的想法(也许我需要使用可变参数模板以使参数的数量灵活,但如果 C++11 标准适用,我必须与我们的技术负责人核实好的)。

理想情况下,我想避免我有两次完全相同的函数但每种类型都有不同的签名(一个用于字符串,一个用于整数)的情况。

提前谢谢了!

4

2 回答 2

3

我会将字符串拆分为字符串(如您所做的那样),然后将它们转换为所需的类型。

您可以使用boost::lexical_cast它,或者std::stringstream

template <typename To, typename From>
To cast(const From &arg)
{
    std::stringstream s;
    s << arg;
    To res;
    s >> res;

    if (s.fail())
    {
        //throw some_exception();
    }

    return res;
}

无论如何,如果您boost有空,这是正确的方法

于 2012-10-04T09:00:04.103 回答
2
#include <algorithm>
#include <string>
#include <sstream>

template <typename T1, typename T2, typename T3>
void parse_string(const std::string& input, T1& out1, T2& out2,
                  T3& out3, char delimeter)
{
  std::istringstream is1(input);

  std::string field;
  for (int i = 0; std::getline(is1, field, delimeter) && i < 3; ++i)
  {
    std::istringstream is2(field);
    switch (i)
    {
    case 0: is2 >> out1; break;
    case 1: is2 >> out2; break;
    case 2: is2 >> out3; break;
    }

    if (is2.fail()) 
    {
      // do something about invalid type conversion?
    }
  }

  // up to you to decide what to do if the string has too
  // many or too few fields
}

lexical_cast 会更安全!

于 2012-10-04T09:29:25.900 回答