nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

template関数でsplit関数を実装する (空白文字列区切り)

template関数でsplit関数を実装する (空白文字列区切り)

template関数を使用することで、複数の型を同じ関数で扱うことができるようになります。

使い方

関数呼び出し時には、通常の関数呼び出しとは異なり、型を指定する必要があります。

const std::vector<std::string> result1 = SplitWords<std::string>(input1);

コード例1

#include <iostream>
#include <vector>
#include <sstream>


template <class T>
std::vector<T> SplitWords(const std::string &line)
{
    std::vector<T> words;
    std::istringstream ss{line};
    std::string buf;
    
    T t;
    int count = 0;
    
    while(ss >> t)
    {
        words.emplace_back(t);
        count++;
    }
    
    std::cout << "Loop count : " << count << std::endl;
    
    return words;
}

int main (void)
{
    const std::string input1 = "abc\n def\n\n ghi\n";
    const std::vector<std::string> result1 = SplitWords<std::string>(input1);
    std::cout << "result 1 size : " << result1.size() << std::endl;
    
    for (const auto & item : result1)
    {
        std::cout << item << std::endl;
    }

    const std::string input2 = "12.3\n 45.6\n 78.9\n";
    const std::vector<double> result2 = SplitWords<double>(input2);
    std::cout << "result 2 size : " << result2.size() << std::endl;
    
    for (const auto & item : result2)
    {
        std::cout << item << std::endl;
    }
    
    const std::string input3 = "1\n 222\n\n 333\n 44\n\n\n";
    const std::vector<double> result3 = SplitWords<double>(input3);
    std::cout << "result 3 size : " << result3.size() << std::endl;
    
    for (const auto & item : result3)
    {
        std::cout << item << std::endl;
    }
    
    EXIT_SUCCESS;
}
Loop count : 3
result 1 size : 3
abc
def
ghi
Loop count : 3
result 2 size : 3
12.3
45.6
78.9
Loop count : 4
result 3 size : 4
1
222
333
44

コード例2(istringstreamのeofメソッドを使った実装)

ifs.eof()の場合は、入力文字列に改行コードがある場合は、ループカウンタが余計に一回実行された。 この方法では、行中の改行文字列'\n'は正しく認識できないため注意してください。

#include <iostream>
#include <vector>
#include <sstream>


template <class T>
std::vector<T> SplitWords(const std::string &line)
{
    std::vector<T> words;
    std::istringstream ss{line};
    std::string buf;
    
    int count = 0;
    
    while(!ss.eof())
    {
        T t;
        ss >> t;
        words.emplace_back(t);
        count++;
    }
    
    std::cout << "Loop count : " << count << std::endl;
    
    return words;
}

int main (void)
{
    const std::string input1 = "abc\n def\n\n ghi\n";
    const std::vector<std::string> result1 = SplitWords<std::string>(input1);
    std::cout << "result 1 size : " << result1.size() << std::endl;
    
    for (const auto & item : result1)
    {
        std::cout << item << std::endl;
    }

    const std::string input2 = "12.3\n 45.6\n 78.9\n";
    const std::vector<double> result2 = SplitWords<double>(input2);
    std::cout << "result 2 size : " << result2.size() << std::endl;
    
    for (const auto & item : result2)
    {
        std::cout << item << std::endl;
    }
    
    const std::string input3 = "1\n 222\n\n 333\n 44\n\n\n";
    const std::vector<double> result3 = SplitWords<double>(input3);
    std::cout << "result 3 size : " << result3.size() << std::endl;
    
    for (const auto & item : result3)
    {
        std::cout << item << std::endl;
    }
    
    EXIT_SUCCESS;
}
Loop count : 4
result 1 size : 4
abc
def
ghi

Loop count : 4
result 2 size : 4
12.3
45.6
78.9
78.9
Loop count : 5
result 3 size : 5
1
222
333
44
44

リンク

*【C/C++】 streamクラスのeofメンバ - http://murakan.cocolog-nifty.com/blog/2009/12/cstreameof-7401.html