• 締切済み

CSV ⇒ 構造体 ⇒ 文字列配列

1,あいうえおあいうえお 3,かきくけこ 2,さしすせそさしすせそさしすせそ 3,たちつてと 2,なにぬねの 1,はひふへほはひふへほはひふへほはひふへほ    ・    ・    ・ といったようなCSVファイルがあります。 まずは、それを typedef struct tagSetInf{  int nPattern; // 1or2or3  char szSearch[256]; // 文字列:最大255バイト }SetInf; という構造体に格納していき、そのszSearchの値を nPatternの値に応じて3種類の文字列配列((例)search1,search2,search3)に 格納したいと思っています。 CSVのレコード数は可変です。(たぶん最大数は100くらいだとは思うのですが・・・) 以上の実現方法を教えてください。よろしくお願いいたします。 環境:Win32 API、C/C++。

みんなの回答

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

数が未定の配列をどうやって確保するかという質問なら malloc で動的に確保する方法があります。 CSVの行数だけ数えてその分の構造体をmallocで確保 構造体にCSVを読み込む 構造体から nPattern == 1, 2, 3 の数を求めそれぞれの数だけ各文字列配列を malloc で確保 mallocのお約束 使い終わったら free しましょう

kenkenpo
質問者

お礼

大変遅くなってしまい、申し訳ありませんでした。 貴重なアドバイスありがとうございました。 今更ですが、現在の進行状況を説明させていただくと、 >CSVの行数だけ数えてその分の構造体をmallocで確保 >構造体にCSVを読み込む の部分までは実装できました。 その後の >構造体から nPattern == 1, 2, 3 の数を求めそれぞれの数だけ各文字列配列を malloc で確保 の部分については、いろいろ試しているのですが上手くいかず、 文字列配列を動的に確保するには至っていません。 大変図々しいお願いだとは思いますが、アドバイス等いただけると幸いです。 ちなみに、以下のソースの最後で free(pSetInf); とすると、落ちてしますのは何故でしょうか。 よろしくお願いいたします。 // 設定ファイル.txtの情報を格納する構造体 typedef struct tagSetInf{  int nPattern;  char szSearch[128]; }SetInf; char *search1[50]; // パターン1の文字列配列 char *search2[50]; // パターン2の文字列配列 char *search3[50]; // パターン3の文字列配列 int num1 = 0; int num2 = 0; int num3 = 0; int c, nLine = 0; // 設定ファイルをオープン if((fp = fopen("設定ファイル.txt", "r")) != NULL){  while ((c = getc(fp)) != EOF){   if (c == '\n'){    nLine++; // CSVの行数をカウント   }  } } // 設定ファイルの行数により、動的に構造体のメモリを確保する SetInf *pSetInf; pSetInf = (SetInf *)mallco(nLine * sizeof(SetInf)); rewind(fp); // ファイルポインタを先頭に戻す while(fscanf(fp, "%d,%s", &pSetInf->nPattern, pSetInf->szSearch) == 2){  if(pSetInf->nPattern == 1){   search1[num1] = pSetInf->szSearch;   num1++;  }else if(pSetInf->nPattern == 2){   search2[num2] = pSetInf->szSearch;   num2++;  }else if(pSetInf->nPattern == 3){   search3[num3] = pSetInf->szSearch;   num3++;  }  pSetInf++; }

kenkenpo
質問者

補足

追加内容 混乱を招く記述をしてしまったのですが、 文字列配列の文字列は128バイト or 256バイトの固定で構いません。 よろしくお願いいたします。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★fscanf() 関数で簡単に。 ・前回のサンプルの readFile() を少し書き換えるだけで出来ると思います。  下に構造体読み込み用に書き換えたのをコピー&ペーストしておく。 // ファイルから構造体に読み込む BOOL readFile( SetInf tag[], int max, LPCTSTR lpFname[] ) {  FILE *fp;  int no;    if ( (fp = fopen(lpFname,"r")) != NULL ){   for ( no = 0 ; no < max ; no++ ){    /*    ★ここで構造体メンバにセット    ・fscanf() を使えば良いかな    ・パターン番号を tag->nPattern に直接セット    ・サーチ文字列を tag->szSearch に直接セット    */    tag++; ←移動   }   fclose( fp );   return TRUE;  }  return FALSE; } // 使い方 SetInf data[ 100 ]; if ( readFile(data,100,"abc.csv") ){  // 正常 } else{  // 異常(ファイルがない) } その他: ・エラーチェックがないので追加などして下さい。 ・以上。

参考URL:
http://www.bohyoh.com/CandCPP/C/Library/fscanf.html
kenkenpo
質問者

お礼

大変遅くなってしまい申し訳ありません。 いつも、大変参考になるアドバイス本当にありがとうございます。 CSVファイルから、構造体に読み込むのは以下の方法で 実現できました。 しかしまだ、その構造体からパターン番号に応じた文字列配列に、 動的に配列を確保して格納するという処理を実装することができません。 今のままですと、それぞれ50個までしか登録できません。 いつもお願いしてばかりで大変申し訳ないのですが、アドバイスをいただけると幸いです。 よろしくお願いいたします。 ちなみに、以下のコードの最後に free(pSetInf); とすると、落ちてしまいます。 // 設定ファイル.txtの情報を格納する構造体 typedef struct tagSetInf{  int nPattern;  char szSearch[128]; }SetInf; char *search1[50]; // パターン1の文字列配列 char *search2[50]; // パターン2の文字列配列 char *search3[50]; // パターン3の文字列配列 int num1 = 0; int num2 = 0; int num3 = 0; int c, nLine = 0; // 設定ファイルをオープン if((fp = fopen("設定ファイル.txt", "r")) != NULL){  while ((c = getc(fp)) != EOF){   if (c == '\n'){    nLine++; // CSVの行数をカウント   }  } } // 設定ファイルの行数により、動的に構造体のメモリを確保する SetInf *pSetInf; pSetInf = (SetInf *)mallco(nLine * sizeof(SetInf)); rewind(fp); // ファイルポインタを先頭に戻す while(fscanf(fp, "%d,%s", &pSetInf->nPattern, pSetInf->szSearch) == 2){  if(pSetInf->nPattern == 1){   search1[num1] = pSetInf->szSearch;   num1++;  }else if(pSetInf->nPattern == 2){   search2[num2] = pSetInf->szSearch;   num2++;  }else if(pSetInf->nPattern == 3){   search3[num3] = pSetInf->szSearch;   num3++;  }  pSetInf++; }

kenkenpo
質問者

補足

追加内容 混乱を招く記述をしてしまったのですが、 文字列配列の文字列は128バイト or 256バイトの固定で構いません。 よろしくお願いいたします。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

残念ながらお答えできません。 自分で考えて出来た所までを書かないと、このサイトでは削除されてしまいます。 以下は、削除時に届くメールから抜粋しました。 >当サイトは、会員の方同士の助け合いによる知識交換を提供させていただく質疑応答の場として運営しており、特定の会員の方に質問、回答の投稿を義務づけ、他の会員の方に何かを依頼してやってもらうというような場でございません。 >課題やレポートなどを質問として投稿する事自体は禁止しておりませんが、「○○についてやってください」など、課題文を丸写しにしたような質問についてはマナー違反であると考えております。 >質問を削除いたしますと回答もあわせて削除されてしまいます。せっかくご回答いただきましたのに申し訳ございませんがご了承くださいますようお願いいたします。 >※当ルールにつきましては、皆様にご理解いただきやすいよう「課題」「レポート」という語句を使用いたしておりますが、課題やレポートではなくても、上記に該当すると考えられるものは、投稿をご遠慮いただいております。

kenkenpo
質問者

お礼

申し訳ありません。 ある程度までは自分で考えていたものがあったのですが、それを載せませんでした。 今後は気をつけたいと思います。

関連するQ&A