2017-02-10 51 views
1

previous question我问我如何阅读和舒适地将字符串矢量转换为整数或双精度的矢量。对和stringstream

现在我简单的扩展类型的载体的对向量的类型(考虑intdouble,甚至std::string,所有启用流类型)用冒号分隔。

例子:

time:5, length:10 

应读为std::pair<std::string, unsigned int>,像这样的东西:

// Here declare what to parse: a string and an uint, separated by a colon 
get_vector<std::pair<std::string, unsigned int>>(s); 

我如何写一个std::stringstream操作员做的伎俩?

我无法弄清楚(或者说)我可以玩getline(我的代码如下)。如果可能,我真的想离开get_vector函数,因为它是

谢谢!

template <class F, class S> 
std::stringstream& operator >> (std::stringstream& in, std::pair<F, S> &out) 
{ 
    in >> out.first >> out.second; 
    return in; 
} 

template <class T> 
auto get_vector(std::string s) -> std::vector<T> 
{ 
    std::vector<T> v; 

    // Vector of strings 
    auto tmp = split(s); 

    // Magic 
    std::transform(tmp.begin(), tmp.end(), std::back_inserter(v), 
        [](const std::string& elem) -> T 
        { 
         std::stringstream ss(elem); 
         T value; 
         ss >> value; 
         return value; 
        }); 

    return v; 
} 
+0

所以在你的代码中'elem'将是字符串''时间:5,长度:10“'? – NathanOliver

+0

当你说你想离开get_vector函数时,你的意思是声明而不是定义,或者是你? –

+0

@NathanOliver elem将会是“time:5”,因为原始字符串已被拆分为逗号分隔的组件。 – senseiwa

回答

2

operator>>收到std::stringstream这在那一刻包含像"time:5"的字符串。操作员需要将该字符串分解为两个令牌,然后将第一个令牌转换为F,将第二个令牌转换为S

执行此操作的一种方法是使用带有自定义分隔符的std::getline。您将以两个std::string令牌结束。例如,这些可以通过两个内部转换器std::istringstream进行转换。

下面是一些代码,你可以尝试:

template <class F, class S> 
std::stringstream& operator >> (std::stringstream& in, std::pair<F, S> &out) 
{ 
    std::string first_token; 
    std::string second_token; 
    std::getline(in, first_token, ':'); 
    std::getline(in, second_token); 

    std::istringstream first_converter(first_token); 
    std::istringstream second_converter(second_token); 

    first_converter >> out.first; 
    second_converter >> out.second; 

    return in; 
} 

您可能要添加一些错误处理的情况时有字符串中没有':'


请注意,如果您不想将输入和输出组合起来,则不应使用std::stringstream。大多数情况下,您需要std::istringstreamstd::ostringstream

0

因为我是英文新人,所以我不知道明白你想要什么。我开玩笑地看到@Christian Hackl做了什么。所以如果这个答案不是 涉及到你想要的东西请告诉我,我会删除它。

我假设你需要从提取,然后把它们放到一个包含std::pair< std::string, std::size_t >

说你有这个字符串可以是一个输入 - 一个vector流:
std::string string("one:1, two:20, three:300, four:40000, five:500000");

有多种方法可以做到这一点,但我这样说!
所以首先你需要拆分这个字符串然后把什么分开,在向量对

std::string string("one:1, two:20, three:300, four:40000, five:500000"); 

std::stringstream io_stream; 

std::basic_regex<char> regex(", "); 
std::regex_token_iterator<std::string::const_iterator> last; 
std::regex_token_iterator<std::string::const_iterator> first(string.begin(), string.end(), regex, -1); 

std::vector< std::pair< std::string, std::size_t > > vector_of_pair; 
std::string str_pair(""); 
std::size_t ui_pair(0); 

while(first != last){ 
    io_stream.clear(); 
    io_stream.seekg(0); 
    io_stream.seekp(0); 

    io_stream << *first << '\n'; 
    std::getline(io_stream, str_pair, ':'); 
    // error: 
    // no match function to call: stream and int 
    // std::getline(io_stream, ui_pair); 
    io_stream >> ui_pair; 

    vector_of_pair.emplace_back(str_pair, ui_pair); 

    ++first; 
} 

测试

for(std::size_t index = 0; index < vector_of_pair.size(); ++index){ 
    std::cout << vector_of_pair[ index ].first << " and " << vector_of_pair[ index ].second << '\n'; 
} 

输出

one and 1 
two and 20 
three and 300 
four and 40000 
five and 500000 

它是如何工作的
天下没有难做的代码来理解。它只是通过std::regex_token_iterator分割字符串,然后在循环它的值发送给is_stream,然后读取线并将其发送到str_pair,但这里因为std::getline已经不能起到提取int类型,我用>>stringstream本身,然后emplace_back到矢量,就是这样。

注意
为:
如何我写一个std :: stringstream的操作员做的伎俩?
我想现在你可以自己做。由于我不确定,我没有用operator>>编写代码。