【C++】最強のSplitクラスを作ろう!【無いから】
1 :
デフォルトの名無しさん :
2005/11/09(水) 00:22:13 Split関数って知ってるよね? 俺はVBやってちょっと使ってみただけなんだけど便利なんだよ。これ。 で、業務で使えるぐらい便利にならんかと色々と考えたわけよ。 んでも、俺って文字列処理あんまよく知らないし苦手なんだよね。 なんで、プログラム晒すと話が中々進まないから、 超便利なSplitクラスの仕様をみんなで考えようというわけよ。 はじめに何もないとアレだからとりあえず俺が考えたとk
boost使えや
boostので十分なんだけど。
boostなくてもstringstreamあれば十分 =======終了========
ワロタ
"【C++】最強のSplitクラスを作ろう!【無いから】"のログを削除します。よろしいですか? →【はい】 [いいえ]
>>2 実はVBのもよく知らないんだけど、
boostのsplitの仕様ってどうなってんの?
8 :
デフォルトの名無しさん :2005/11/09(水) 00:40:12
boostみてきた。 なんかあんまよさそうじゃないなぁ・・・。 とりあえずね。 1.デリミタ文字を指定できるようにしたい。 2.トークン3つ目の読み込みで処理を中断する等、指定したトークン数で途中で処理を止められるようにしたい。 3.指定した文字と文字の間にある文字列はデリミタの適用をぬけて取得できるようにしたい。 4.指定した文字列を発見したら、処理を中断するようにしたい。 5.中断したところから再開したい。 ぐらいは入れたいと思ってるんだけどどうだろうか? 1と3が実現すればCSVファイルぐらいは一発で読めると思う。
別に
>>8 ぐらいは難しくはないだろ?
どこでもやってるし。
10 :
デフォルトの名無しさん :2005/11/09(水) 00:48:15
>>9 >どこでもやってるし
じゃあ、ソース頂戴。
俺、文字列処理得意じゃねぇんだ。
11 :
デフォルトの名無しさん :2005/11/09(水) 00:51:30
どっかにあるとは思うんだよね。 コンパイラとか作ってる奴等の集まりなら 定石みたいのがたくさん転がってそうだけど。 英語読むのも、本読むのも、正直好きじゃねぇし。 しかも、そういう奴等と波長があわないらしく、人生において会ったことが無い。
12 :
デフォルトの名無しさん :2005/11/09(水) 00:55:04
しかも、これって字句解析の初歩みたいなとこだろ。 そこだけくださいってのもねぇ・・・
その程度の処理ならboost::regexで充分だろ。 boost::spiritすらいらない。
14 :
デフォルトの名無しさん :2005/11/09(水) 07:03:18
だからstringstreamを使えと。 streamのメソッドとstringのメソッド両方使えば全部出来るだろうが。
17 :
デフォルトの名無しさん :2005/11/09(水) 19:31:46
>>15-16 適当に答えてねぇ?
>>8 の内容を全部同時に満たせなきゃ駄目なんだよ。
わかってる?
CSVファイルなんかで、改行が入ってるとダブルコーテーションに囲まれてる文字列は
改行にデリミタ適用したくないでしょ?
それと一度に読むことしかできないと、文字列の途中でデリミタを変更したりとかできないでしょ?
そういうことよ。
>>17 std::stringstreamやboost::tokenizerを内部的に使って、
>>8 を満たすものを作るのは駄目か?
一から自分で作ったほうが早い(苦笑)
ていうかその程度なら、標準とboostだけで既に作ってる奴が 数千人はいるだろ、国内だけでも。 俺が作ったオナニー言語にすら備わってるぞw
C++の思想は便利なネジ・クギを用意して、後は自由になんでも 作ってくださいってことなのに、 特定の用途にしか使えないクソ仕様ライブラリが欲しいって奴は、 そもそもC++使うなと。 アホな特定用途に特化したスクリプト言語や環境使ってシコシコ してろ馬鹿。
CSV読み込みたいのなら、CSV読み込みクラス作るべきだな。 どうせCSV以外に使わないんだから。
あれもこれもと欲張るといいこと無いからな。特に、
>>1 みたいな奴にとっては。
25 :
デフォルトの名無しさん :2005/11/10(木) 22:18:56
>>8 の内容を実装してみるとわかるけど、boostなんて役に立たない。
できるとかレスつけてた奴って
>>1 よりレベル低いね。
27 :
デフォルトの名無しさん :2005/11/10(木) 22:50:07
>>26 やらないで言ってるでしょ。
boostは
>>8 の内容の実装には糞の役にも立たない。
>>8 の内容だけなら tokenizer で普通に実装できる。
>>17 で行ってる途中でデリミタを変えるのは難しいかもしれないけど。
>>28 カッコ内でかこまれた部分のデリミタの回避はどうやるの?
>>29 escaped_list_separator のコンストラクタの第3引数
31 :
デフォルトの名無しさん :2005/11/10(木) 23:00:41
>>30 tokenizerでできるんじゃないの?
>>30 escaped_list_separator は tokenizer ライブラリの一部。
tokenizer の第1テンプレート引数に使う。
>>30 ああ、突っ込むのね。
変なクラスの使い方してんなぁw
>>28 >>8 の内容が全部できるなら、中断したときにデリミタを変更して再開すればできるんじゃないの?
なんでできないの?
それじゃあこのスレッドはここらへんから 地球シュミレータで動かしている地球をシュミレーションするソフトを なんとなく真似して開発してみるスレッドに変わったわけか。
シュミレータ(笑)
そこらのおっさんなら間違えてもしょうがないが、 プログラマーには間違って欲しくないな。
実際の発音はシュのほうが近いよ ミじゃないけどね
実際の発音もシミュ(スィミュ)だと思うぞ
スィなんて表記は正しい日本語じゃないよ おまえら脳みその替わりに苺か薔薇でも詰まってるんじゃね?
バラ肉でした(爆)
boost::spilit で
>>8 はできる。
マジレスしちゃだめw
47 :
デフォルトの名無しさん :2006/04/26(水) 06:47:57
>>45 かなり前のレスだけど4と5ってどうやってやればいいの?
48 :
デフォルトの名無しさん :2006/04/26(水) 09:05:47
>>47 リファレンスを流し読みしただけだが、イテレータ使えばいいだけだろ
単に分割するだけなくCSV読み込みが出来るといい。
単に書き散らすのでなくちゃんとした日本語を書けるといい。
結局boostで出来たのw?
Boost.Spirit使えばいいじゃない
なんで?
boost::token_iterator<>::base()を使ってもいいならデリミタの変更もできるな。 ドキュメントされていないのが嫌な感じではあるが。
60 :
デフォルトの名無しさん :2006/12/07(木) 01:21:50
文字列区切るだけなら、ポインタを移動していって、目的の文字列を発見したら'\0'に置き換えればいいんじゃないの? CSVの場合なら、 a = "abc,efg,hij,klm,n\0"な文字列を a = "abc\0efg\0hij\0klm\0n\0"にするだけの話だろ? 変換過程で、変換した数を保持してやって、それぞれの文字列にアクセスするのは、 b = a for( int i = 0 ; i<=(目的のトークン) ; i++ ) { b = b + lstrlen( b ) + 1; } でアクセスできるじゃん
61 :
デフォルトの名無しさん :2006/12/07(木) 07:01:14
>>60 誰もそんなこと聞いてネェよw
>>8 の内容はboostの何使っても微妙なところで引っかかってできない。
繰り返しいうけど微妙なところで引っかかるの。
脳内だけでできると思わないほうがいい。
そういっておきながらどこが微妙なのかについては具体的に触れないのなw
63 :
デフォルトの名無しさん :2006/12/07(木) 12:40:52
>>61 a = "abc,efg,\"h,i\nj\",klm,n\0"を
a = "abc\0efg\0\"h,i\nj\"\0klm\0n\0"って事?
split( 変換する文字列, 区切り文字, 例外文字, 英数大文字小文字を区別するか )
見たいな関数を作って、例外文字から例外文字の間は変換作業を中止すればいいんじゃないの?
まあ、こうなってくると面倒くさくなるから、おいらなら、
split( 変換する文字列, 区切り文字列, 英数大文字小文字を区別するか )
にしておいて、読み込むデータをエクセルなんかで、","から"\t"に区切りを変更するけどね
>>62 俺のやり方だと途中で中断してまた再開するってのができねぇ。
>>62 そもそも中断っていってもどこで中断すればいいのか検討がつかない。
中断する位置によってはかなり変な動作をすることになるし。
この辺は実装するにあたっていい具合の仕様が見付からない。
また、指定された文字に閉じられた箇所はデリミタ無しってのが
一括で区切り文字を抜くことができなくてちょっと難しい。
そもそも、デリミタを途中でチェンジできる仕様みたいだから一括は全部駄目だけど。
中断する条件によってこの辺はかなり難しくなると思う。
boostのtokenizerを素直に使えば要素一つ読む毎に制御が戻るが、 それじゃだめなのか?
すまんが「俺のやり方だと」だけじゃどこが問題なのか分らん。
俺のやり方だと出来るとしか言いようがない。
boost::tokenizerならtoken_iterator使うだけで1,2,5はできるだろ。
>>8 の3と4は関数オブジェクトを適当に書いてfilter_iteratorでtokenizerに渡せば解決。
デリミタを途中で替えたいなら、tokenizerを使わずにTokenizerFunctionを 直接使えばなんとかなるはず。 …と思ったがescaped_list_separatorには外部からアクセスできない内部状態があるな。 「最後の要素が空でない」という条件下ではうまくいくけど、一般的には無理っぽい。
>>69 それってそれぞれを別々にやる場合だけじゃない?
例えば中断したときにデリミタをチェンジして再開とかできんの?
あと、トークン3つめまではデリミタXX、その先の処理は、
文字列XXと○○で囲まれた文字へのデリミタ■■の適用を除外し、
枠外はデリミタ△△、■■でトークンを取得・・・とか。
72 :
70 :2006/12/08(金) 01:05:12
いや、文字列の最後を明示的にテストすればいいのか。 泥臭いけど、できないことはないということで。
>>71 >>59 の通り、token_iterator<>::base()で元のイテレータ型で現在位置を示すイテレータが手に入るから、
別のtokenizerを作ってやるなりtokenizer::asign呼ぶなりで途中からの変更が可能。
typo。疲れてるな。寝よう。 -asign +assign
ちゅうか、途中で区切り文字を変える必要はあるのか? a = "abc,efg,\"h,i\nj\",klm,n\0"を a = "abc\0efg\0\"h\0i\nj\"\0klm\0n\0"にしてから a = "abc\0efg\0\"h,i\nj\"\0klm\0n\0"にすればいいんじゃないのか?
>>73 ,75
例えば↓のような文字列をトークン単位で分割できるか?
for(i=0;i<size;i++){unko("うんこ?\"Yes/No\"");}
結果は
for ( i = 0 ; i < size ; i + + ) { unko ( " うんこ? "Yes/No" " ) ; }
って感じになるようにしたい。
(tokenizerはなんか俺のしたかったことがことごとく
できないような気がしたんだが今となってはなんでできなかったのか正直忘れてしまったぜw
ただ、俺がアフォだったからじゃなくて、なんかの機能がなくてできなかった気がするぜw)
それは字句解析。tokenizerの仕事じゃないよ。 boost::spiritでも使いなされ。
>>76 なんか、
>>1 で言ってるのと全然違うもんじゃないですか...
そう言う形でと言うのなら、検索の仕方から全然違う物になると思いますよ
単純に、","であるとか"\r\n"であるとか、"<BR>"であるとかを句切り符号にして区切るようなルーチンであれば、対象の先頭から何も考えず調べればいいけれど
その場合だと、半角記号(空白含むダブルクォーテーション除く)と一致するかどうかを調べる方が早いと思うのですが...
for(i=0;i<size;i++){unko("うんこ?\"Yes/No\"");}
この場合だと、
'(' ')' ';' '<' '+' '{' '}'
と一致する文字を探すルーチンを作る方が簡単ではないでしょうか?
この場合、単純な1文字の検索なんで、検索の工夫といっても限られるとは思いますが...
>>77 ,78
なるほど。
そこまでいくとパーサジェネレータみたいなの作ったほうが早いのか・・・。
結局、どこまでサポートするか?
って話になるのか。
でも、あんまり厳密なのもいらないし、特に演算子みたいなのも気にする必要もないから
パーサジェネレータまでは必要ないなぁ。
>その場合だと、半角記号(空白含むダブルクォーテーション除く)と一致するかどうかを調べる方が早いと思うのですが...
>for(i=0;i<size;i++){unko("うんこ?\"Yes/No\"");}
>この場合だと、 '(' ')' ';' '<' '+' '{' '}'
例えばこれも { と ( を区切り(+トークン)として認識出来さえすればはじめの一発目で
for ( i=0;i<size;i++ ) { unko ( "うんこ?\"Yes/No\"" ) ; }
ここまでもってこれちゃうからこの辺の幅を捨てるのは惜しいと思うんだよね。
spiritが大げさだというならregexはどうだ?
81 :
デフォルトの名無しさん :2006/12/14(木) 16:40:35
(っ´▽`)っ上げ
82 :
デフォルトの名無しさん :2006/12/26(火) 02:47:06
一年も経つのに、まだできてないの? というか、作るスキルないから、boost流用って流れになってるのか?
xpressiveのtoken_iteratorでいいじゃない
84 :
デフォルトの名無しさん :
2007/04/18(水) 22:03:15