备注:代码有备注和思路,函数接口以后补充!!!
代码示例:基于score.CSV文件数据修改(get_avg_score.c)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct student
{
char name[32];
double score[3];
}stu_t;
/*
* 获取文件行数
* 函数:fopen()打开文件,fgets()接取字符
* 思路:统计行数需要遍历文件有多少个换行符(\n)
*/
int GetFileLine(char *pfilename)
{
FILE *fp = NULL;
char ch = 0;
int line = 0;
fp = fopen(pfilename, "r");
if (NULL == fp)
{
perror("fail to fopen");
return -1;
}
while (1)
{
ch = fgetc(fp);
if (EOF == ch)
{
break;
}
if ('\n' == ch)
{
line++;
}
}
fclose(fp);
return line;
}
/*
* 获取学生数据
* 函数:fgets()接取一行字符串,strtok()对字符串进行分割,strcpy()拷贝学生姓名,atof()将字符串转换成浮点型(double)
* 思路:通过fgets()接取字符串,再用strtok()对字符串进行分割,然后用atof()对字符串的转换,将数据写入堆区空间
*/
int GetStuInfo(stu_t *pstu, char *pfilename)
{
FILE *fp = NULL;
int i = 0;
int j = 0;
char *pret = NULL;
char tmpbuff[1024] = {0};
fp = fopen(pfilename, "r");
if (NULL == fp)
{
perror("fail to fopen");
return -1;
}
while (1)
{
memset(tmpbuff, 0, sizeof(tmpbuff));
pret = fgets(tmpbuff, sizeof(tmpbuff), fp);
if (NULL == pret)
{
break;
}
strcpy(pstu[i].name, strtok(tmpbuff, ","));
for (j = 0; j < 3; j++)
{
pstu[i].score[j] = atof(strtok(NULL, ","));
}
i++;
}
fclose(fp);
return 0;
}
/*
* 写入学生数据
* 函数:fprintf()将堆区空间数据写入文件中
*/
int PutStuInfo(char *pfilename, stu_t *pstu, int line)
{
FILE *fp = NULL;
int i = 0;
fp = fopen(pfilename, "w");
if (NULL == fp)
{
perror("fail to fopen");
return -1;
}
for (i = 0; i < line; i++)
{
fprintf(fp, "%s,%.2lf,%.2lf,%.2lf,%2lf\n", pstu[i].name, pstu[i].score[0], pstu[i].score[1], pstu[i].score[2], (pstu[i].score[0] + pstu[i].score[1] + pstu[i].score[2]) / 3);
}
fclose(fp);
return 0;
}
int main(int argc, const char *argv[])
{
char filename[128] = {0};
stu_t *pstu = NULL;
int len = 0;
printf("请输入需要操作的文件(.CSV):\n");
scanf("%s", filename);
len = GetFileLine(filename);
pstu = (stu_t *)malloc(len * sizeof(stu_t));
if (NULL == pstu)
{
perror("fail to malloc");
return -1;
}
GetStuInfo(pstu, filename);
PutStuInfo(filename, pstu, len);
free(pstu);
return 0;
}