C言語ケーススタディ Excelで作ったデータ(CSVファイル)の読み込みプログラム2
2014年10月より個人の方を対象に、Study C無料提供を開始しました。
C言語を勉強中の方は、学習・教育に最適なC言語インタープリタのStudy Cを使ってみてください(個人の方は無料です)。
大学・高専・高校などの教育機関での採用実績も多数あるロングセラー商品Study Cが、個人向けに無料提供を始めました。
インタープリタの手軽さに加え、ゲームや3Dタートルグラフィックで楽しく勉強したりと、C言語の学習を強力にサポートします。
また、このようなボタンの用意されているページでは、掲載しているプログラムをStudy Cに直接ロードし実行したりすることができます。
Study C無料利用についての詳細は、このページを参照してください。
1番目 " 2番目 , 3番目 ",データに','が存在するとCSV形式の区切り文字である','と区別がつかなくなってしまいます。 そのため','が含まれる項目は"..."の形式で囲まれます。 ','同様'"'も特殊な文字のためデータに'"'が含まれる場合は特殊な扱いになります。 '"'が含まれる項目も"..."の形式になりデータの'"'は'""'と2文字に変換されます。 上記のデータは次のように変換されます。
データ "..."で囲む データの'"'は'""'に変換 1番目 " """ """" 2番目 , "," "," 3番目 ", ""," ""","結局Excelで出力したCSVファイルは次のようになります。
1,2,3 11,12,13 21,22,23 """",",",""","今回は上記のようなデータにも対応できるようにGetCSVItem関数を修正します。
#include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("コマンドの入力形式が間違っています.\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("ファイルがオープンできません[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("データが不正です[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("エラー(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("エラー(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("エラー(3)\n"); break; } if(*wp != '\0'){ printf("エラー(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1, dq_flag; dq_flag = 0; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } if(*wp == '"'){ dq_flag = 1; wp++; } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(dq_flag == 1){ if(*wp == '"'){ if(*(wp+1) == '"'){ wp++; } else{ wp++; while(*wp == ' ' || *wp == '\t') wp++; if(*wp != ','){ buff[i1] = '\0'; if(*wp == '\0') return(wp); return(NULL); } wp++; buff[i1] = '\0'; break; } } } if(dq_flag == 0 && *wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); }