我有一个我正在尝试处理的CSV文件,看起来类似于下面的文件。这种格式已经在遗留软件中使用,所以不幸的是我无法改变它。如您所见,该文件分为两个部分 - 在此示例中,一个部分用于项目,一个部分用于这些项目中的部分。
ID,Description,Make,Model,Serial,Parts
200,Fridge,Samsung,S4450,SX05948596,1x34.4x22
354,Dishwasher,Bobs,BB45,BFDD34848,3x34.1x55.4x2
ENDITEMS
STARTPARTS
ID,Description,Price,Created
34,Bolt,4.33,08/05/15
22,Nut,1.20,10/10/12
ENDPARTS
我目前正在尝试使用Microsoft文本驱动程序和CDatabase
/ CRecordset
来解析文件,但遇到了问题。似乎引擎与一些关于使用什么数据类型的字段混淆 - 特别是第一部分和第二部分使用不同类型的字段。
例如,如果我在索引1(描述)上调用recordSet.GetFieldValue()
,那很好,并将其解析为字符串,因为第1节和第2节都使用字符串。如果我在索引4上调用它,我会遇到问题 - 对于索引(Model)使用字符串的第一部分,但在第二部分中索引(Created)使用日期类型。 GetFieldValue()
调用中的结果返回null。
我试过调用CRecordSet.GetFieldValue(index, CDBVariant, SQL_C_CHAR)
强制它以字符串形式读取索引,但我仍然返回null。如果可能的话,我希望避免在解析之前删除文件。
现在我还是C ++的新手,所以这里可能会有一些明显的错误,但这是我的测试代码(printType()
方法只打印出CDBVarient的类型和值):
CString fileDir = "C:\\";
CString fileName = "test.CSV";
CString conString;
CString queryString;
conString.Format("DRIVER={Microsoft Text Driver (*.txt; *.csv)};DSN='';DBQ=%s;", fileDir);
queryString.Format("SELECT * FROM [%s]", fileName);
CDatabase db;
CRecordset rs;
rs.m_pDatabase = &db;
db.OpenEx(conString);
if (rs.Open(AFX_DB_USE_DEFAULT_TYPE, queryString))
{
int count = rs.GetODBCFieldCount();
for (int i = 0; i < count; i++)
{
CODBCFieldInfo fieldInfo;
rs.GetODBCFieldInfo(i, fieldInfo);
CDBVariant varValue;
rs.GetFieldValue(i, varValue, SQL_C_CHAR);
std::cout << i << " " << fieldInfo.m_strName << ":\t";
printType(&varValue);
std::cout << std::endl;
}
}