任务
将excel表格信息导入程序中进行处理,通用性增强
所需
- c语言运行平台
- 数据表格 ,格式如下图
步骤
#define FILENAME "grade.csv"
#define TITLE1 "姓名"
#define TITLE2 "学号"
#define TITLE3 "成绩"
#define TITLE4 ""
#define HEADERMAXLEN 100 //表头最大字符总长
#define TITLEMAXLEN 100 //单个标题最大字符长度
#define TITLEMAXNUM 20 //标题最大数量
#define DATAMAXLEN 100 //数据最大字符总长
1.读入表头
FILE* fp;
fp = fopen(FILENAME, "r");
char* pHeader;
char* pTitle;
int colNum = 0;//记录表格数据列数
int* data2col;//记录需要的数据所在列
char csvHeader[HEADERMAXLEN];
char title[TITLEMAXNUM][TITLEMAXLEN];
char lineData[TITLEMAXNUM][DATAMAXLEN];
int readAll = 0;//判断是否到文件结尾
//读入表头信息
fscanf(fp, "%s", &csvHeader);
//分割表头各个标题
for (pHeader = csvHeader; *pHeader != '\0'; pHeader++)
{
colNum++;
pTitle = title[colNum];
while (*pHeader != ',' && *pHeader != '\0')
{
*pTitle++ = *pHeader++;
}
*pTitle = '\0';
if (*pHeader == '\0')
break;
}
//优化有误,不可随意清除行数
/*
for (int i = colNum; i > 0; i--)
{
if (*title[i] == '\0')
colNum--;
else
{
for (int i = 1; i <= colNum; i++)
//cout << "第" << i << "列:" << title[i] << endl;
break;
}
}
*/
优化内容:
将空列清除
知识归纳:
字符串判空屡次失败,最终采用:
*title[i] == '\0'
- 字符串判定内容相同用函数strcmp(),用=
=只比较数组地址 - 空字符串为"",空字符为’\0’
但结果运行错误,反应过来:不可随意清除空列,由于这是csv格式,故行列关系固定,不可因标题改变而改变下面内容,故取消清除空列,还原版本
- 定位所需数据
//标记数组置零
data2col = (int*)malloc(sizeof(int) * (TITLENUM +1));
for (int i = 1; i <= TITLENUM; i++)
{
data2col[i] = 0;
}
//找到所需数据对应列
for (int i = 1; i <= colNum; i++)
{
if (strcmp(title[i], TITLE1) == 0)
data2col[1] = i;
if (strcmp(title[i], TITLE1) == 0)
data2col[2] = i;
if (strcmp(title[i], TITLE1) == 0)
data2col[3] = i;
if (strcmp(title[i], TITLE1) == 0)
data2col[4] = i;
}
- 读入所需数据
while (readAll == 0)
{
//读入数据
for (int i = 1; i <= colNum; i++)
{
if (readCell(fp, lineData[i]) == 0)
{
readAll = 1;
break;
}
}
//可更改增加退出数据读入灵活性
for (int i = 1; i <= TITLENUM; i++)
{
if (data2col[i]&&isEmpty(lineData[i]))
readAll = 1;
}
//记录读入数据
for (int i = 1; i <= colNum; i++)
{
if (i == data2col[1])
cout << TITLE1 << ": " << lineData[i] << " ";
if (i == data2col[2])
cout << TITLE2 << ": " << lineData[i] << " ";
if (i == data2col[3])
cout << TITLE3 << ": " << lineData[i] << " ";
if (i == data2col[4])
cout << TITLE4 << ": " << lineData[i] << " ";
}
cout << endl;
}
1.字符串判空函数
/****************************************
Function:判定字符串是否为空
Input:字符串
output:无
return:为空返回1,否则返回0
****************************************/
int isEmpty(char* s)
{
if (strcmp(s, "") == 0)
return 1;
else
return 0;
}
2.读入一单元格内容函数
/****************************************
Function:读入一单元格内容
Input:数据所在文件
output:单元格内容
return:读入数据返回1,读至文件末尾返回0
****************************************/
int readCell(FILE* fp, char* s)
{
char temp[DATAMAXLEN],ch;
char *pTemp=temp;
if(!feof(fp))
if ((ch = fgetc(fp)) == '\n')
{
;
}
else if (ch == ',')
{
strcpy(s, "\0");
return 1;
}
else
*pTemp++ = ch;
while (!feof(fp)&&(ch = fgetc(fp)) != ',' && ch != '\n')
{
*pTemp++ = ch;
}
if (feof(fp))
return 0;
*pTemp = '\0';
strcpy(s, temp);
return 1;
}
结果验证
写在后面
基本具有可应用性,如有调整,后期在此基础上进行补充即可