逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个很长的字符串。
CSV文件由任意数目的记录行组成,记录行之间以某种换行符分隔;每行记录由任意数目的字段组成,每个字段之间以分隔值分隔。
CSV文件的生成
char plate[16]={0};//车牌号
char data1[20]={0};//开始日期
char data2[20]={0};//结束日期
//保存车牌数据
char *p = new char[0xFFFFFF];//开辟文件字符串空间,大小未知,所以尽量大一些
u32_t len=0;//文件字符串总长度
u32_t len1=0;//每行记录的长度
strcpy(p, "车牌号,开始时间,结束时间\r\n");//填充记录第一行:逗号分隔字段,回车换行分隔记录行。第一行一般都是标题行。
len1 = strlen(p+len);//本行记录长度
len += len1;//累加出总长度
for(int i=0;i<m_u32PlateCount;i++)//记录总条数
{ //逐行往后追加
((CListCtrl*)GetDlgItem(IDC_LIST1))->GetItemText(i, 2, plate, sizeof(plate) );
((CListCtrl*)GetDlgItem(IDC_LIST1))->GetItemText(i, 3, data1, sizeof(data1) );
((CListCtrl*)GetDlgItem(IDC_LIST1))->GetItemText(i, 4, data2, sizeof(data2) );
sprintf(p+len,"%s,%s,%s\r\n",plate,data1,data2);//填充记录下一行:逗号分隔字段,回车换行分隔记录行
len1 = strlen(p+len);//本行记录长度
len += len1;//累加出总长度
}
//保存csv文件
CFile file( "lpr.csv", CFile::modeCreate|CFile::modeWrite );
file.Write( p, len+1 );//保存个数加1,把最后一个字符串结束符也存起来,这样解析时才能正确找到结尾
file.Close();
delete[] p;//释放空间
CSV文件的解析
char NO[10]={0};//编号
char plate[16]={0};//车牌号
char data1[20]={0};//开始日期
char data2[20]={0};//结束日期
//打开csv文件
CFile file( "lpr.csv", CFile::modeRead );
DWORD dwCount = file.GetLength();//文件长度
char *p = new char[dwCount+1]; //开辟空间
file.Read( p, dwCount );
file.Close();
//解析csv文件
char *q = p;//新建一个指针进行滑动,保留p指针用于后边的内存释放。
while( q = strstr( q, "\r\n" ) )//查找行尾标志
{
q += 2;//跳过行尾,指向下一行。首行一般是标题行,不处理
if( 3 != sscanf( q, "%[^,],%[^,],%[^\r]", plate,data1,data2 ) )//获取字段
break;//失败,跳出
//成功
//填充列表内容
((CListCtrl*)GetDlgItem(IDC_LIST1))->InsertItem(m_u32PlateCount,"");
((CListCtrl*)GetDlgItem(IDC_LIST1))->SetItemText(m_u32PlateCount,1,itoa( m_u32PlateCount, NO, 10 ));
((CListCtrl*)GetDlgItem(IDC_LIST1))->SetItemText(m_u32PlateCount,2,plate);
((CListCtrl*)GetDlgItem(IDC_LIST1))->SetItemText(m_u32PlateCount,3,data1);
((CListCtrl*)GetDlgItem(IDC_LIST1))->SetItemText(m_u32PlateCount,4,data2);
//记录数量增加
m_u32PlateCount++;
}
delete[] p;//释放空间