C++のboostのtokenizerのエラー

このQ&Aのポイント
  • C++でboostを使用し、テキストファイルから読み込んだ1行のテキストをtokenizerでセパレーションし、文字列を編集したい。
  • テキストファイルから読み込む際に問題はなく、カンマで区切られた文字列をrecordに格納する際にエラーが発生。
  • エラーの原因としては、カンマで区切られた文字列に空白や不要な文字が含まれている可能性がある。解決するためには、カンマで区切る前に文字列から不要な空白や文字を取り除く必要がある。
回答を見る
  • ベストアンサー

C++のboostのtokenizerのエラー

現在C++でboostを使用して、テキストファイルから読み込んだ1行分のテキストをtokenizerでセパレーションして、文字列を編集したいと考えています。 それで、次のようなプログラムを作成しました。 char_separator<char> sep(" "); tokenizer< char_separator<char> > tokens( record, sep ); typedef tokenizer< char_separator<char> >::iterator Iter; for( Iter it=tokens.begin(); it!=tokens.end(); ++it ) record = *it + ","; 1行分の文字列は”record”に入っています。 最初に”---------------------------------------------------”という文字列が読み込まれて、このプログラムでは正常に処理されて、 ”---------------------------------------------------”で変化はありませんがrecordに正常に格納されます。 しかし、次の行の”001. リモート, 2012/06/12 09:15:49”というのを読み込んだ際に、for文でカンマで区切られた文字列をrecordに格納する際にエラーが出てデバッグが中断してしまいました。 このようなプログラムでの問題点と解決方法を教えて頂けないでしょうか。 どうぞ、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

#include <iostream> #include <sstream> #include <string> #include <boost/tokenizer.hpp> using namespace std; using namespace boost; void tokenize(const string& record) { char_separator<char>sep(" "); typedef tokenizer< char_separator<char> > tokenizer_t; tokenizer_t tokens( record, sep ); for( tokenizer_t::iterator it=tokens.begin(); it!=tokens.end(); ++it ) cout << '[' << *it << ']' << endl; } int main() { istringstream stream( "----------------------------------\n" "001. リモート, 2012/06/12 09:15:49\n" "002. ローカル, 2012/06/13 10:20:50\n" "----------------------------------\n"); string line; while ( getline(stream, line) ) { tokenize(line); } } /* 実行結果 */ [----------------------------------] [001.] [リモート,] [2012/06/12] [09:15:49] [002.] [ローカル,] [2012/06/13] [10:20:50] [----------------------------------] ...何の問題もありませんねぇ。

diy_sunny
質問者

お礼

回答頂きありがとうございました! tokenizerのサンプルプログラムも頂き大変ありがとうございました。 ちゃんとテキストを分けることができるようになりました。今こんな感じで利用しています。 char_separator<char> sep(" "); //分割結果の表示 string record_test; typedef tokenizer< char_separator<char> >::iterator Iter; tokenizer< char_separator<char> > tokens( record, sep ); for( Iter it=tokens.begin(); it!=tokens.end(); ++it ) record_test = record_test + *it + ","; impl_->record = record_test.substr(0); iterator_range<string::iterator> r = find_first( impl_->record,"------" ); if(r) impl_->record = "\r\n"; //impl_->data << *it << ","; }

関連するQ&A

  • boostを利用したプログラムのコンパイルでエラー

    boostを初めて利用しようと思い、ファイルをダウンロードして、bjamを使ってインストールしました。そして以下のようなテスト用のプログラムを作成しました。 #include <boost/tokenizer.hpp> using namespace boost; int main(void) {   char_separator<char> sep(" \t\n");   tokenizer<char_separator<char> > tokens("aaa bbb ccc", sep);   return 0; } これをbcc32によりコンパイルすると、以下のようなエラーがいくつか発生してコンパイルができませんでした。 エラー E2489 c:\borland\bcc55\include\boost-1_33_1\boost/mpl/aux_/integral_wrapper.hpp 45: オプションコンテキスト応答深度の上限を超過: 再帰をチェックしてください なぜ、このようなエラーが出るのでしょうか。ちなみに、cygwin+gccではコンパイルおよび実行が可能でした。 ご存じの方がいらっしゃったらよろしくお願いします。(WinXPです)

  • C言語 文字列格納

    テキストファイルから整数データ又は文字列を読み込んで配列に格納する動作についての質問です。 テキストファイルが1行区切りの整数型なら1次元配列で for(i = 0; i < maxSize; i++) { fscanf(fp,"%d", &data[i]); } テキストファイルが1行区切りの文字列なら2次元配列で for(i = 0; i < MAXSIZE; i++) { if (fscanf(fp,"%s", &data[i][300]) == EOF) break; } for(j = 0; j < i; j++) printf("%s\n", data[j]); みたいな具合に格納できたんですが、 テキストファイルが1行区切りのデータではなく、空白文字区切りの文字データだった場合、それぞれどのようにして配列に格納すればいいかがわかりません。 イメージとしては、1文字目から見ていって空白が出ればそこで切って格納していくというかんじなのですが・・・ 質問の内容がわかりにくいかもしれませんが、是非教えてください。お願いします。

  • C言語でポインタを勉強しています。

    C言語でポインタを勉強しています。 それで、以下のようなプログラムを作成したのですが思ったようにいきません。何が原因でしょうか。 標準入力から全ての文字列を読み取った後、発言者と、「です」を付加した文字列を表示するプログラム 1 # include < stdio . h > 2 # include < string . h > 3 4 5 typedef enum { 6 NAME , // 発言者 7 COMMENT , // 発言 8 MAX _ RECORD _ ARRAY // レコード の 属性 の 数 9 } RecordArrayIndex ; 10 11 12 static const int MAX _ RECORD = 100 ; // 最大 の レコード 数 13 static const int MAX _ STRING = 32 ; // 発言者及 び 発言 の 最大文字数 ( ナル文字 を 含 む ) 14 15 // 関数 プロトタイプ 宣言 16 // record に 発言者 ( name ) と 、 その 発言 ( comment ) を 設定 する 。 17 void setNameAndCommentToRecord ( char * name , char * comment , char * record []) ; 18 // record の 発言 の 語尾 に 「 です 」 を 付 け 加 える 。 19 void appendCommentMeow ( char * record []) ; 20 21 int main ( void ) { 22 char * record [ MAX _ RECORD ][ MAX _ RECORD _ ARRAY ] ; 23 char * name = " 太郎 " ; 24 25 int currentIndex = 0 ; 26 for ( ;; ) { 27 char comment [ MAX _ STRING ] ; 28 if ( gets ( comment ) == NULL ) { 29 break ; 30 } 31 setNameAndCommentToRecord ( name , comment , record [ currentIndex ]) ; 32 appendCommentMeow ( record [ currentIndex ]) ; 33 currentIndex ++ ; 34 } 35 36 int const availableIndex = currentIndex ; 37 for ( int index = 0 ; index < availableIndex ; index ++) { 38 printf ( "% s : 「 % s 」 \ n " , record [ index ][ NAME ] , record [ index ][ COMMENT ]) ; 39 } 40 41 return 0 ; 42 } 43 44 void setNameAndCommentToRecord ( char * name , char * comment , char * record []) { 45 record [ NAME ] = name ; 46 record [ COMMENT ] = comment ; 47 } 48 49 void appendCommentMeow ( char * record []) { 50 strcat ( record [ COMMENT ] , " です " ) ; 51 } 52

  • C言語の課題で困っています;

    C言語の課題で困ってます; 学校の課題で、キーボードから文字を入力する(最大80文字)。入力された文字列と、入力した文字列を逆順にした文字列を表示する。(malloc,freeを使って作成して下さい) ヒントで #invlude <stdio.h> void main(void){ char *buf; //入力文字列用 char *seq; //入力文字列用コピー用 char *rev; //逆順文字列用 int lec, i; buf =(char*)malloc(81); printf("文字列を入力:"); scanf("%s"buf ); for(i = 0; buf[i] ??? '\0'; i++){ } Ien = i; /* lenに文字列の長さが入る */ seq = ???(??? + 1); /* len+1文字文確保*/ for(i = 0; ???; i++){ seq[0] = buf[0]; } free(buf); rey = ???(len + 1); for(i = 0; < len; i++){ rev[len - i - 1] = seq[i]; } ren[i] ~ '\0'; printd("入力文字列 : %s\n",sep); でたんですが、全然分からなくて足りない部分の答えを教えてもらえると助かります;

  • C言語でのカンマ区切りについて

    結果テキストファイルから特定の値のみ抽出するプログラムを作成しているのですが、思うように動いてくれません。どなたか教えてくださいませんか。お願いします。 <テキストファイルの形式> 様々な文字や記号slm,0.070000,-53458.000000様々な文字や記号 これが1行に4つ程含まれるものが10行ほどあるのですが、 2つ目のカンマの後の数値部分のみ抽出したいのです。 <プログラム> char line[MAXLINE]; char a1[]="slm"; char *r; char *s[2]; while (fgets(line, MAXLINE, fp) != NULL){ if(strstr(line, a1)!=NULL){ for (r = line ;r = strstr(r, a1); r += 27 ){ for(int p=0;p>2;p++){ s[p]=strtok( strstr(r, a1), "," ); printf("%s",s[3]); } } printf(" \n"); i++; } } そこでこのようなプログラムを作ってみたのですが、実行すると何も表示されません。 どなたか改善策を教えてください。本当に困っています。

  • Visual C++を 用いたテキストファイル読み込み(応用)

    Microsoft Visual C++ 2008 Express Editionを使っています。 テキストファイルは 約5000行×6列の数値(のみ)になっております。(列間にスペースあり) いくつかある5000×6行テキストファイルの中から、ファイル名を入力することで任意のテキストファイルにアクセスし、さらに6列のデータをそれぞれ別の配列に格納するコンソールプログラムを考えていますが行き詰まっています。例えば、1列目を配列1、2列目を配列2、・・・といった具合です。 詳しい方、どうかよろしくお願いいたします。

  • Cの文字列関連の質問です。よろしくお願いします。

    Cの文字列関連の質問です。よろしくお願いします。 『読み込んだ文字列がナル文字を含めて15文字以下であれば、その文字列をそのまま格納し、そうでない場合、読み込んだ文字列の先頭14文字とナル文字を格納する』 という条件を満たすプログラムを作成しました。 #include <stdlib.h> #include <string.h> #include <stdio.h> int main(void) { int num; char (*p)[15]; printf("文字列の個数: "); scanf("%d", &num); p = (char (*)[15])malloc(num * 15); if (p == NULL) puts("記憶域の確保に失敗"); else { int i; char tmp[100]; /* 書込み */ for (i = 0; i < num; i++) { printf("p[%d]: ", i); scanf("%s", tmp); sprintf(p[i], "%.14s", tmp); } /* 表示 */ for (i = 0; i < num; i++) printf("p[%d]: %s\n", i, p[i]); free(p); } return 0; } この場合は、ちゃんと条件を満たした結果が出ました。 ここで24行目の『sprintf(p[i], "%.14s", tmp);』を『strncpy(p[i], tmp, 14);』に変更する明らかに結果がおかしくなります。 strncpyを使った方法に変更する場合、どのように修正を行えばいいのでしょうか? 長々と書いてしまいましたが、よろしくお願い致します。

  • C言語 ファイル内のデータと入力したデータの重複

    テキストファイルを読み込み、入力したデータとの重複がないかどうかを調べたいのですが、 わからない点があるため、質問させていただきます。 -------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> int main() {    FILE *fp;    char datafile[];= "sample.txt";    char buff[512]; //読み込んだ1行分のデータを格納    char *data[1000]; //読み込んだデータを格納    int data_c = 0; //データの数    char str[256]; //入力された文字列を格納    int i;    int check; //重複チェック         (中略)    //ファイルを1行ずつ読み込み、その長さのメモリを確保し、値をコピー    while(fgets(buff, sizeof buff, fp) != NULL) {      data[data_c] = (char*)malloc(strlen(buff) + 1);      strcpy(data[data_c++], buff);    }         (中略)    //文字列を入力    fgets(str, 256, stdin);    check = 0;    //すでにあるデータと入力したデータの重複を調べる    for(i=0; i<data_c; i++) {      if(strcmp(data[i], str) == 0) {      check = 1;      break;      }    }         (中略) -------------------------------------------------------- 例えば読み込むファイルに5行書かれていた場合、 data[0]からdata[4]に確保したメモリの先頭アドレスが格納されますよね? ということはdata_cの値は4となるのですが、 その後のファイルデータと入力したデータの重複を調べるところで、 for(i=0; i<data_c; i++) となっており、data[0]からdata[3]までの4行分しか調べられないことになります。 なぜ、i<=data_cではなく、i<data_cとなっているのか、わかりましたら教えていただけますでしょうか。

  • PHPプログラムについて

    読み込んだテキストファイルを1行ずつ検索し、特定の文字が見付かればそれに続く文字列を配列に格納するというプログラムを作りたいです。 そこで指定文字列の出現以降の文字列を取り出すというstrchr関数を用いて 作成を試みたのですが上手くいきません。 何か別の方法があれば教授をお願いします。

    • 締切済み
    • PHP
  • C言語

    以下のC言語のプログラムを教えてください。 お願いします。 (1)標準入力から文字列(2 文字以上)を入力し,文字数を計上すると共に,入力された文字列の逆順に入れ替える処理を実現してください.なお,以下の要件を満たしたプログラムを作成してください. ・ 入力された文字列は,char 型の配列(要素数50)で受け取ること ・ 文字数を計上するcount 関数(引数:配列のアドレス,戻り値:文字数)を定義 し,main 関数より呼び出すこと ・ 文字列を逆順に入れ替えるreverse 関数(引数:配列のアドレス,戻り値:無し) を定義し,main 関数より呼び出すこと ・ 標準出力の処理は,main 関数で記述すること 【プロトタイプ宣言】 int count(char *str); void reverse(char *str); 【実行結果】 文字列を入力してください(2 文字以上) apple 文字数 = 5 入れ換え前 apple 入れ換え後 elppa (2)char 型の配列(要素数50)を2 つ宣言し,標準入力から2 つの文字列を入力してください.そして,格納した字列を入れ替える関数(swapstr 関数)を作成し,入れ替え前と入れ替え後の配列内の値(文字列)を配列名とともに標準出力するプログラムを作成してください. 【プロトタイプ宣言】 void swapstr(char *str1, char *str2); 【実行結果】 2 つの文字列を入力してください apple strawberry 入れ換え前 配列str1 = apple 配列str2 = strawberry 入れ換え後 配列str1 = strawberry 配列str2 = apple

専門家に質問してみよう