2023年12月2日发(作者:)

C语言读取CSV文件  最近做一个模块,需要通过C语言实现CSV文件的读取,自己这边参考晚上大神的文章,重新开发做了封装,也希望对大家有点帮助。

  

  ReadCSVFile.h是我自己定义实现csv文件读写的头文件,同样的,ReadCSVFile.c是我自己定义实现csv文件读写的源文件。

  

  使用方法可以从下面的main函数看出来,首先用ReadCsvData()读取Csv文件到一个数组中,然后就可以使用ShowCsvData()读取想要的某行的数据了,最后结束时要用FreeCsvData()释放空间。#include "ReadCSVFile.h" int main(void) { char *filename=""; ReadCsvData(filename); //读取csv数据 ShowCsvData(); //通过控制台显示读取的csv数据 FreeCsvData(); //释放动态数组 return 1; }运行结果如下:

(不需要关心数据这个只是个普通的测试文档,告诉大家这个方法是可行的)封装文件如下:int GetTotalLineCount(FILE* fp); //计算csv文件中的总行数 int GetTotalColCount(FILE * fp); //计算csv文件中的总列数(以第一行的列数为基准) int AssignSpaceForData(int inumdata); //通过指针*giCsvData给数据动态分配内存空间 void FreeCsvData();      //释放动态数据内存 int ReadCsvData(char* csvFilePath); //读取Csv中数据(本例默认数据类型为int) void ShowCsvData(); //通过控制台显示读取的csv数据ReadCsvFile.c:

//

// 源文件Read csv file data

//#include "readCSVFile.h"//计算csv文件中的总行数int GetTotalLineCount(FILE * fp){

int i = 0; char strLine[MAX_LINE_SIZE]; fseek(fp,0,SEEK_SET); while (fgets(strLine, MAX_LINE_SIZE, fp)) i++; fseek(fp,0,SEEK_SET); return i;}//计算csv文件中的总列数(以第一行的列数为基准)int GetTotalColCount(FILE * fp){

int i = 0; char strLine[MAX_LINE_SIZE]; fseek(fp,0,SEEK_SET); if (fgets(strLine, MAX_LINE_SIZE, fp)) { i=strlen(strLine)/2; //因为csv文件以逗号','作为分隔符,所以此处除以2 } else { fseek(fp,0,SEEK_SET); return -1; } fseek(fp,0,SEEK_SET); return i;}// 通过指针*giCsvData给数据动态分配内存空间int AssignSpaceForData(int inumdata){ giCsvData=NULL; giCsvData = (int*)malloc(sizeof(int)*inumdata);

if (giCsvData == NULL) return 0; memset(giCsvData, 0, sizeof(int)*inumdata); return 1;}// 释放动态数据内存void FreeCsvData(){ free(giCsvData); giCsvData = NULL;}// 从csv文件中读取数据int ReadCsvData(char* csvFilePath){ FILE* fCsv; char *ptr; char strLine[MAX_LINE_SIZE]; int i; int j; // 已经有了数据,则先删除 if (giCsvData != NULL) FreeCsvData(); // 打开文件 if( fopen_s( &fCsv, csvFilePath, "r" ) != 0 ) { printf("open file %s failed",csvFilePath); return -1; } else { // 确定动态数组的大小,然后开辟空间 // 确定动态数组的大小,然后开辟空间 giNumRow = GetTotalLineCount(fCsv); giNumCol = GetTotalColCount(fCsv); giNumData = giNumRow*giNumCol; AssignSpaceForData(giNumData); // 读取数据 for (i = 0; i < giNumRow; i++) {

j=0; if(fgets(strLine,MAX_LINE_SIZE,fCsv)) { ptr=strtok(strLine,","); //返回字符数组中字符‘,’之前的字符,剩下的保留到静态数组中(此方法vs认为不安全) //可以尝试使用strtok_s替换 while(ptr!=NULL) { giCsvData[i*giNumCol+j]=atoi(ptr); //将字符转换为int类型数据并保存到动态数组中 j++; ptr = strtok(NULL,","); //将从文件中读取的当前行剩余字符数组,读取字符‘,’前面的字节 } } } // 关闭文件 fclose(fCsv); } return 1;}//通过控制台显示读取的csv数据void ShowCsvData()

{ int i; int j; for (i = 0; i < giNumRow; i++) { printf("Line %i :",i+1); //输出每行的行号 Line : for (j=0;j

//

// 头文件Read csv file data

//#pragma once#include #include // for memset#include // for malloc, free#include // for strtok#define MAX_LINE_SIZE 256 //fgets函数读取的最大字节数int* giCsvData ; //动态分配数据内存的指针int giNumData ; //读取的数据字节数int giNumRow ; //每行的字节数int giNumCol ; // 每列的字节数int GetTotalLineCount(FILE* fp); //计算csv文件中的总行数int GetTotalColCount(FILE * fp); //计算csv文件中的总列数(以第一行的列数为基准)int AssignSpaceForData(int inumdata); //通过指针*giCsvData给数据动态分配内存空间void FreeCsvData(); //释放动态数据内存int ReadCsvData(char* csvFilePath); //读取Csv中数据(本例默认数据类型为int)void ShowCsvData(); //通过控制台显示读取的csv数据