1. 程式人生 > >C語言解析csv檔案

C語言解析csv檔案

#include 
#include 
#include 

typedef enum CSV_ENCLOSURE_STATUS_ENUM
{
    CSV_ENCLOSURE_NONE,
    CSV_ENCLOSURE_ENTER,
    CSV_ENCLOSURE_EXIT
}CSV_ENCLOSURE_STATUS_ENUM;

#define DELIMITER_CHAR ','
#define ENCLOSURE_CHAR '"'
#define CSV_MAX_LINE 512

typedef struct csv_string
{
	char buf[32];
	short len;
}pcsv_string;

typedef struct user
{
	pcsv_string family[5];
	int pos;
}puser;

void push_string (char ch, pcsv_string *str)
{
	if (str->len > 30) {
		return;
	}
	
	str->buf[str->len] = ch;
	str->len++;
	return;
}
CSV_ENCLOSURE_STATUS_ENUM StateAction(char ch, CSV_ENCLOSURE_STATUS_ENUM quote_status, pcsv_string *str, puser *user)
{
	if ((DELIMITER_CHAR == ch) && (CSV_ENCLOSURE_ENTER != quote_status)) {
		memcpy((char *)(&(user->family[user->pos])), str->buf, str->len);
		user->family[user->pos].len = str->len;
		memset(str, 0, sizeof(pcsv_string));
		if((++(user->pos)) > 4) {
			return -1;
		}
		return CSV_ENCLOSURE_NONE;
	}

	if (ENCLOSURE_CHAR == ch) {
		if (CSV_ENCLOSURE_EXIT == quote_status) {
			push_string(ch, str);
			return CSV_ENCLOSURE_ENTER;
		} else {
			
           /*CSV_ENCLOSURE_NONE -> CSV_ENCLOSURE_ENTER
            		CSV_ENCLOSURE_ENTER -> CSV_ENCLOSURE_EXIT*/
            return quote_status + 1;
		}
	}

	push_string(ch, str);
	return quote_status % CSV_ENCLOSURE_EXIT;
}


static int my_fgets(char *string, int n, FILE* stream)
{
    int i;
    char ch;

    for (i = 0; i < n - 1; i++) {
        if (fread((void *) &ch, 1, 1, stream) != 1) {
            return 0;
        }        
        *(string + i) = (char) ch;

        if (ch == '\n') {
            i++;
            break;
        }
    }

    *(string + i) = '\0';
    
    return i;
}

void ParseRecord()
{
    CSV_ENCLOSURE_STATUS_ENUM quote_status;
	struct csv_string str;
	struct user filed;
	FILE *fp;
	int count, i;

	char line[CSV_MAX_LINE];
	fp = fopen("user.csv", "r");
    if(fp ==NULL ) {
        return;
    }
    if (my_fgets(line, CSV_MAX_LINE, fp) == 0) {
        fclose(fp);
        return;
    }

	memset(line, 0, CSV_MAX_LINE);    
    while ((count = my_fgets(line, CSV_MAX_LINE, fp)) != 0) {
		memset(&filed, 0, sizeof(struct user));
		memset(&str, 0, sizeof(struct csv_string));
		quote_status = CSV_ENCLOSURE_NONE;
		for (i = 0; i < count; i++) {
			quote_status = StateAction(line[i], quote_status, &str, &filed);
			if (quote_status == -1) {
				break;
			}
		}

		if (CSV_ENCLOSURE_ENTER != quote_status) {  /*Record finished*/
			printf("--%s \n--%s\n --%s\n", filed.family[0].buf, filed.family[1].buf, filed.family[2].buf);
		}
	}
	
	fclose(fp);
	return;
}

int main()
{
	ParseRecord();
	
	return 0;
}