- ベストアンサー
ファイル読み込みとmap処理
Visual C++ 2008 Express Edition 環境です。 入力テキストファイルを読み込み、空白で単語を区切り、単語すべてをmapにいれるという処理のプログラムを書こうとしています。 perlでいうところのsplit, 配列へのpushをC++でstrtokとmapでならかけると思いました。 入力ファイルは input1.txt--------------- cat dog mice human mosquito beetle spider ------------------------- プログラムは #include <stdio.h> #include<iostream> #include <map> #include <vector> int main( ) { FILE *input_file1; input_file1 = fopen("input1.txt", "r"); char str[256]; char *token; std::vector<char *> my_vector; // while (fgets(str, 256, input_file1) != NULL) { token = strtok( str , " " ); while( token != NULL ){ my_vector.push_back(token) ; printf("%s\n",token); token = strtok( NULL , " " ); } } printf("starting vector loop\n"); std::vector<char *>::iterator it = my_vector.begin(); // while( it != my_vector.end() ) // { printf("%s\n",*it); ++it; // } fclose(input_file1); return 0; } というふうにしました。 cat dog mice human mosquito beetle spider というような出力がなされるものと思ったのですが、実行してみると mapを使ったループ(全要素)出力は mosquito uito le mosquito beetle spider というふうに出力されてしまいます。 strtokで単語を分ける部分は問題なく出力で確認できるので、問題はmapの作り方やポインタだと思うのですが原因がわかりません。 問題点、解決策がお分かりになる方、よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
map 関係ないですよね。 直接的な原因は strtok で得られたポインタが str 配列の位置を指しているので、行を読むたびに str の中身は書き換えられているためです。 ポインタを vector に入れるのではなくて、文字列をコピーして入れるように変更しましょう。 また、空白で区切られているなら、ファイルから ifstream を作成して operator>> で読み込んだ方が楽だと思います。
その他の回答 (1)
- Tacosan
- ベストアンサー率23% (3656/15482)
それだと my_vector を std::vector<char *> ではなく std::vector<std::string> で定義することになりますよね. で, そうなら実は my_vector の定義を変えればいいだけだと思います. std::string のコンストラクタは push_back で自動的に呼び出されるんじゃないかな.
補足
アドバイスありがとうございます。 std::vector<std::string> my_vector; std::string str1 = "*token" ; my_vector.push_back(str1) ; としてみたのですが、 出力が(null)となってしまいます。 perlで非常に適当にやっていたことがC++では私にとっては非常に難しく混乱していますが、もうすこし粘ってみます。
補足
ありがとうございます。 >ポインタを vector に入れるのではなくて、 >文字列をコピーして入れるように変更しましょう。 strtokのあつかいがまだよくわかっていないのですが、 トークンをstringにコピーというのは token = strtok( NULL , " " ); std::string mojiretu ; mojiretu = token; my_vector.push_back(mojiretu) ; このようにするのでしょうか?