はじめに
業務でC++のコードを触った時に、「読み込んだファイルをカンマ区切りにする」という処理を実装するのにJavaのsplit
のような関数を使おうと思って探したものの、split関数は存在しないことが分かりました。
最新の言語仕様だとsplitに相当する新しい関数が追加されているかもしれませんが、C++の素人としてはちょっと衝撃を受けました。
今回はこちらのサイトを見よう見まねで「split関数」を作ってみたので、そのコードを記事としてまとめることにしました。
作成したコード
- 以下のコードはpaiza.ioで動作を確認しました。
- ですが、そもそもC++の書き方というか流儀のようなものが良く分かっていないので、色々間違っている点があるかもしれません...
- 色々と調べたところ、
getline
関数を使うと簡単にsplit的な操作ができると書かれていたため、今回はその方法を採用しました。 -
getline関数のリファレンスを見ると、第1引数は
std::basic_istream
という型でしたが、ここではこちらのサイトに倣ってstringstream
型を使っています。-
stringstream
型とstd::basic_istream
型の関係を少し調べてみたものの、親子関係のクラスであるのかは分かりませんでした。
-
- 私の用途だと区切り文字はカンマになることが大半なので、split関数のプロトタイプ宣言にデフォルト引数として
','
を設定しています。- こちらのページを見ると、関数宣言とプロトタイプ宣言の両方でデフォルト引数を設定するとエラーになると書かれていたので、それに従って記述しました。
- 引数
text
が空文字の場合のチェックを入れていますが、これは余り意味が無いかもしれません... - 出力部分では1行ごとに
endl
でフラッシュしていますが、実用上は毎行フラッシュするのは非効率だと思うので、ここは改めた方が良いかもしれません。
Main.cpp
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
// split関数のプロトタイプ宣言
vector<string> split(const string text, const char delimiter=',');
int main(void){
string text = "100-0005,東京都千代田区丸の内1丁目,東京駅";
vector<string> cols = split(text);
for (int i=0; i<cols.size(); i++) {
cout << cols[i] << endl;
}
}
/**
* 文字列を区切り文字で区切って、vector型で返却する。
* text: 対象となる文字列。
* delimiter: 区切り文字。デフォルト値はカンマ。
*/
vector<string> split(const string text, const char delimiter) {
vector<string> columns;
if (text.empty()) {
return columns;
}
stringstream stream{text};
string buff;
while (getline(stream, buff, delimiter)) {
columns.push_back(buff);
}
return columns;
}
実行結果
100-0005
東京都千代田区丸の内1丁目
東京駅
その他
- C言語のprintf関数の代わりに
cout
を使っていますが、この名前はどうやら「character output」の略らしいということが分かって何となくスッキリしました。- 上にも書いたようにC++はド素人なので、最初は「しーあうと」って何だろうと考えてしまいました...