Excelで作ったデータ(CSVファイル)の読み込みプログラム2
C言語ケーススタディ

Study C Ver2販売開始のお知らせ

 C言語の勉強や教育用に最適です。
 2004/8/23よりStudy C Ver2の販売を開始しました。
 Study C Ver2の新しい機能については
 こちらをご参照ください。
C言語でゲームプログラマーを目指す方へ
 ■C言語ゲームプログラミング講座
 C言語でのゲームプログラミングを解説する講座
 始めました。

"..."形式のデータを作成するために、前回のExcelデータの次の行に下記の3個のデータを追加します。
1番目	"
2番目	,
3番目	",
データに','が存在するとCSV形式の区切り文字である','と区別がつかなくなってしまいます。 そのため','が含まれる項目は"..."の形式で囲まれます。 ','同様'"'も特殊な文字のためデータに'"'が含まれる場合は特殊な扱いになります。 '"'が含まれる項目も"..."の形式になりデータの'"'は'""'と2文字に変換されます。 上記のデータは次のように変換されます。

	データ		"..."で囲む		データの'"'は'""'に変換
1番目	"		"""			""""
2番目	,		","			","
3番目	",		"","			""","
結局Excelで出力したCSVファイルは次のようになります。
1,2,3
11,12,13
21,22,23
"""",",",""","
今回は上記のようなデータにも対応できるようにGetCSVItem関数を修正します。
(1)項目の先頭文字が'"'かどうかで処理を分けます(dq_flagを1にセットします)。
(2)dq_flagが1の場合は','ではなく'"'を終了条件とします。
(3)dq_flagが1の場合は'"'が2個連続する場合は終了とせず1個の'"'データとして取り扱います。


#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);
}
Study Cにロードする Study Cにロードし編集する ブラウザとの連携機能が使用可能なStudy Cのバージョンなどについて... 「run csvdata1.csv」のように実行する必要があるので実行ボタンはありません

お問い合わせ先 C言語のトップページに戻る Copyright(C) 2003 潟Iーキッド