CSV形式のテキストファイルを読み込む


カンマやタブで各データが区切られた

2,-3,1,-1,-3
1,2,-3,1,6
3,-1,1,2,-4
2,1,2,0,2

のようなテキストファイルを読み込む.

まずfopenでファイルを開き,fgetsで読み込みバッファに1行読み込む. fgetsでは改行(\n)まで読み込むので,\nを\0に置き換える.

次にstrchrで最初のカンマのポインタを求め,strncpyを使って 読み込みバッファの先頭からカンマの1文字手前までを テンポラリな文字配列にコピーする. バッファの先頭ポインタおよび最初のカンマのポインタをそれぞれpおよびposとすると, コピーするバイト数は(pos-p)となる. テンポラリ文字配列の終端に\0を追加し,データが実数ならばatofなどを使って変換する.

pを最初のカンマの次の文字へのポインタに置き換える. すなわちp=++pos;とし,上記の手順を繰り返す.

もしstrchrがNULLを返したら,pがポイントしている文字から\0までにカンマが存在しないので, strcpy(strncpyではない)を使ってpから\0までをテンポラリ文字配列にコピーする. コピー後,pに\0を代入する.

最後まで読み込んだら(gfgetsがNULLを返したら),fcloseでファイルを閉じるのを 忘れないように. 以下は実際のプログラム例である. この例では読み取ったデータを実数型配列に代入している.

    #define BUFFER_SIZE  64

    int i, j, len, separator;
    char line[ BUFFER_SIZE ], word[ BUFFER_SIZE ], *p, *pos;
    FILE *fp;

    fp = fopen( "input.dat", "r" );
    separator = ',';
    i = 0;
    while ( fgets( line, BUFFER_SIZE, fp ) != NULL ){
       len = strlen( line );
       if ( len > 0 && line[ len - 1 ] == '\n' ){
          line[ len - 1 ] = '\0';
       }
       j = 0, p = line;
       while ( *p != '\0' ){
          pos = strchr( p, separator );
          if ( pos != NULL ){
             strncpy( word, p, pos - p ); 
             word[ pos - p ] = '\0';
             p = ++pos;
          }
          else{
             strcpy( word, p );
             *p = '\0';
          }
          a[ i ][ j ] = atof( word );
          j++;
       }
       i++;
    }
    fclose( fp );

お問い合わせはメールにて: akasaka@klc.ac.jp

戻る
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送