首先,需要?jiǎng)?chuàng)建兩個(gè)類:CCsvFile(派生自CStdioFile,用于從屋里文件中讀取數(shù)據(jù))和CCsvRecord(派生自CObject,適合作為CCsvFile類的Object映射成員,包含指定行的數(shù)據(jù)。
1)CCsvRecord類的創(chuàng)建
由于每個(gè)CSV記錄都包含很多列,所以增加一個(gè)名為m_arrCloumns的CStringArray類型的成員變量(該變量包含記錄的真正數(shù)據(jù)):
protected:
CStringArray m_arrColumns;
接下來(lái),編寫構(gòu)造函數(shù),獲得包含以逗號(hào)分隔記錄的字符串?dāng)?shù)值。使用C語(yǔ)言的strtok函數(shù)來(lái)遍歷字符串尋找逗號(hào),每當(dāng)找到一個(gè)逗號(hào)的時(shí)候,變量的token就包含逗號(hào)前面的值。然后,將這個(gè)值添加到m_arrColumns數(shù)組中。
char DELIMITERS[] = ",";
CCsvRecord::CCsvRecord(LPTSTR lpszRecord)
{
char *token;
token = strtok(lpszRecord, DELIMITERS);
while(NULL != token)
{
m_arrColumns.Add(token);
token = strtok(NULL, DELIMITERS);
}
}
最后,添加返回m_arrCloumns數(shù)據(jù)的大小和檢索與一列相關(guān)的數(shù)據(jù)
UINT CCsvRecord::GetNbrOfColumns()
{
return m_arrColumns.GetSize();
}
CString CCsvRecord::GetColumn(UINT uiColumn)
{
CString strColumn;
if (((uiColumn >= 0) && (uiColumn <= (GetNbrOfColumns() - 1))))
{
strColumn = m_arrColumns[uiColumn];
}
return strColumn;
}
2)CCsvFile類的創(chuàng)建
首先,定義CCsvFile對(duì)象的集合,使用模板化的集合來(lái)保證類型的安全,并定義數(shù)組m_CsvRecordArray。EnsOfFile值是一個(gè)枚舉型的值,用來(lái)判斷是否到達(dá)文件尾。FileExists判斷文件是否存在。m_dwNumberOfRecords返回?cái)?shù)組的大小,即表示文件中包含的記錄數(shù)。
typedef CTypedPtrArray<CObArray, CCsvRecord*> CCsvRecordArray;
class CCsvFile : public CStdioFile
{
public:
CCsvFile(LPSTR lpszFileName);
CCsvFile(CString& strFileName);
~CCsvFile();
protected:
void Initialize(LPSTR lpszFileName);
public:
enum
{
EndOfFile = -1
};
public:
static BOOL FileExists(LPCTSTR lpszFileName)
{
return (0 == (_access(lpszFileName, 4)));
}
protected:
DWORD LoadRecords();
protected:
DWORD m_dwNumberOfRecords;
public:
DWORD GetNumberOfRecords()
{
return m_dwNumberOfRecords;
}
protected:
CCsvRecordArray m_CsvRecordArray;
public:
UINT GetStartPosition();
void GetNextAssoc(UINT& rPosition, CCsvRecord** ppCsvRecord);
};
利用Initialize對(duì)兩個(gè)構(gòu)造函數(shù)進(jìn)行初始化,讀取物理文件并得出包含的記錄數(shù)
CCsvFile::CCsvFile(LPSTR lpszFileName)
{
Initialize(lpszFileName);
}
CCsvFile::CCsvFile(CString& strFileName)
{
Initialize(strFileName.GetBuffer(0));
}
void CCsvFile::Initialize(LPSTR lpszFileName)
{
m_dwNumberOfRecords = 0;
ASSERT(lpszFileName != NULL);
ASSERT(AfxIsValidString(lpszFileName));
if (CCsvFile::FileExists(lpszFileName))
{
if (Open(lpszFileName, CFile::modeRead))
{
m_dwNumberOfRecords = LoadRecords();
}
}
}
DWORD CCsvFile::LoadRecords()
{
m_dwNumberOfRecords = 0;
CCsvRecord* pCsvRecord;
CString strRecord;
while (ReadString(strRecord))
{
pCsvRecord = new CCsvRecord(strRecord.GetBuffer(0));
ASSERT(pCsvRecord);
if (pCsvRecord)
{
m_CsvRecordArray.Add(pCsvRecord);
}
strRecord.ReleaseBuffer();
}
return m_CsvRecordArray.GetSize();
}
增加兩個(gè)遍歷記錄數(shù)組的函數(shù),GetStrarPosition和GetNextAssoc函數(shù)
UINT CCsvFile::GetStartPosition()
{
UINT uiPosition;
if (0 < m_CsvRecordArray.GetSize())
{
uiPosition = 0;
}
else
{
uiPosition = CCsvFile::EndOfFile;
}
return uiPosition;
}
void CCsvFile::GetNextAssoc(UINT& uiPosition, CCsvRecord** ppCsvRecord)
{
UINT uiNewPosition = CCsvFile::EndOfFile;
*ppCsvRecord = NULL;
UINT nRecords = m_CsvRecordArray.GetSize();
if (uiPosition >= 0 && uiPosition <= (nRecords - 1))
{
*ppCsvRecord = m_CsvRecordArray[uiPosition];
if ( (uiPosition + 1) <= (nRecords - 1) )
{
uiNewPosition = uiPosition + 1;
}
}
uiPosition = uiNewPosition;
}
最后,編寫西溝函數(shù)來(lái)清楚前面分配的CCsvRecord對(duì)象:
CCsvFile::~CCsvFile()
{
CCsvRecord* pCsvRecord;
for (int i = m_CsvRecordArray.GetUpperBound(); i > -1; i--)
{
pCsvRecord = m_CsvRecordArray[i];
m_CsvRecordArray.RemoveAt(i);
ASSERT(pCsvRecord);
if (pCsvRecord)
{
delete pCsvRecord;
}
}
VERIFY(0 == m_CsvRecordArray.GetSize());
}
3)打印和顯示CSV文件

單擊Open事件,在實(shí)例化CCsvFile之后,只需在for循環(huán)中使用GetStratPosition和GetNextAssoc函數(shù)來(lái)檢索CCsvRecord對(duì)象。并對(duì)每條記錄調(diào)用InsertDataIntoListView函數(shù)。
void CCViewCSVDlg::OnButton1()
{
CFileDialog dlg(true);
if (IDOK == dlg.DoModal())
{
try
{
m_strFileName = dlg.GetPathName();
UpdateData(FALSE);
CCsvFile file(dlg.GetPathName());
CCsvRecord* pCsvRecord;
for (UINT uiRow = file.GetStartPosition();
CCsvFile::EndOfFile != uiRow;)
{
// get the actual record
file.GetNextAssoc(uiRow, &pCsvRecord);
if (pCsvRecord)
{
InsertDataIntoListView(uiRow, *pCsvRecord);
}
}
}
catch(CFileException* pe)
{
pe->ReportError();
}
}
SizeAllColumns();
}
void CCViewCSVDlg::InsertDataIntoListView(UINT uiRow, CCsvRecord& csvRecord)
{
// For each column in the passed record
for (int iCol = 0; iCol < csvRecord.GetNbrOfColumns(); iCol++)
{
// If this is the first row in the listview
if (uiRow == 1)
{
// Create the listview columns.
CString strColumnName;
strColumnName.Format("Col %ld", iCol);
m_lstFileContents.InsertColumn(iCol, strColumnName);
}
if (iCol == 0)
m_lstFileContents.InsertItem(m_lstFileContents.GetItemCount(),
csvRecord.GetColumn(iCol));
else
m_lstFileContents.SetItemText(m_lstFileContents.GetItemCount()-1,
iCol,csvRecord.GetColumn(iCol));
}
}
最后,設(shè)置好列表框的每列的寬度
void CCViewCSVDlg::SizeAllColumns()
{
CHeaderCtrl* pHeader = m_lstFileContents.GetHeaderCtrl();
ASSERT(pHeader);
if (pHeader)
{
// Turn off redraw until the columns have all
// been resized
m_lstFileContents.SetRedraw(FALSE);
for (int iCurrCol = 0;
iCurrCol < pHeader->GetItemCount();
iCurrCol++)
{
m_lstFileContents.SetColumnWidth(iCurrCol, LVSCW_AUTOSIZE);
int nCurrWidth = m_lstFileContents.GetColumnWidth(iCurrCol);
m_lstFileContents.SetColumnWidth(iCurrCol,
LVSCW_AUTOSIZE_USEHEADER);
int nColHdrWidth = m_lstFileContents.GetColumnWidth(iCurrCol);
m_lstFileContents.SetColumnWidth(iCurrCol,
max(nCurrWidth, nColHdrWidth));
}
// Now that sizing is finished, turn redraw back on and
// invalidate so that the control is repainted
m_lstFileContents.SetRedraw(TRUE);
m_lstFileContents.Invalidate();
}
}
4)相關(guān)函數(shù):
token = strtok(lpszRecord, DELIMITERS);
typedef CTypedPtrArray<CObArray, CCsvRecord*> CCsvRecordArray;
return (0 == (_access(lpszFileName, 4)));
ASSERT(AfxIsValidString(lpszFileName));
for (int i = m_CsvRecordArray.GetUpperBound(); i > -1; i--)
m_CsvRecordArray.RemoveAt(i);
VERIFY(0 == m_CsvRecordArray.GetSize());
pCsvRecord = new CCsvRecord(strRecord.GetBuffer(0));
strRecord.ReleaseBuffer();
m_lstFileContents.InsertColumn(iCol, strColumnName);
m_lstFileContents.InsertItem(m_lstFileContents.GetItemCount(),csvRecord.GetColumn(iCol));
m_lstFileContents.SetItemText(m_lstFileContents.GetItemCount()-1,iCol,csvRecord.GetColumn(iCol));
m_lstFileContents.SetRedraw(FALSE);
m_lstFileContents.SetColumnWidth(iCurrCol, LVSCW_AUTOSIZE);
int nCurrWidth = m_lstFileContents.GetColumnWidth(iCurrCol);
m_lstFileContents.SetRedraw(TRUE);
m_lstFileContents.Invalidate();
posted on 2009-07-29 23:06
The_Moment 閱讀(2902)
評(píng)論(2) 編輯 收藏 引用 所屬分類:
VC實(shí)踐