It is found that it only reads and writes a row in the file, and can only be used as a local variable, or read or write. It cannot be used simultaneously, not as a class variable, let alone extended. Moreover, it can only be implemented under the MFC condition. What if we need to be in a module? What about a database? In non-MFC? However, I think its reading and traversing algorithms and writing algorithms are good. Therefore, based on this, I have made changes according to my work requirements, it also achieved good results in the test.
Generally, to read a CSV file, we need:
1. It can meet both the MFC and non-MFC requirements;
2. Read rows by row instead of one row, because there may be more than one row;
3. After reading a row, you need to analyze and obtain all parsed element items for the separator (generally ","), and the number of elements in each row is not necessarily the same;
4. When writing a CSV file, you must add a separator (generally ",") between the elements of each row. Even the elements may include: colons ("")., comma (","), how do we solve such special characters?
5. As an encapsulation class, there is room for future improvement and expansion.
Okay, let's just move on to the Code:
XCFileStream. h
# If _ MSC_VER> 1000
# Pragma once
# Endif
# Ifndef _ XCFILESTREAM_H __
# Define _ XCFILESTREAM_H __
/// Hide dependent files
/// C System File
/// C ++ System File
# Include <string>
# Include <list>
# Include <vector>
Using namespace std;
# Include <windows. h>
/// Other library header files
/// This project header file
/// No error
# Define XC_ERR_NONE 0
/// Invalid file name or unspecified File Format
# Define XC_ERR_INVALID_FILE_NAME (-1)
/// Read and write the xun-test File
Class CXCFileStream
{
Public:
CXCFileStream (void );
~ CXCFileStream (void );
/*
* Function: Read a CSV file, analyze the content, and store it in a container.
* Parameter description:
* [In] lpszFilename-CSV file to be read;
* [In, out] vlStr-stores the analyzed CSV content
* Return value:
* Error code
* Note: This is a special purpose (not clear yet). It is not a vector <list <string>, but a vector <list <string>.
*/
Const int ReadCsvData (LPCTSTR lpszFilename, vector <list <string> & vlStr );
/*
* Function: writes the content in the container to a CSV file after being typeset, laid out, and added as separators.
* Parameter description:
* [In] lpszFilename-CSV file to be read;
* [In] vlStr-stores the analyzed CSV content
* Return value:
* Error code
* Note: This is a special purpose (not clear yet). It is not a vector <list <string>, but a vector <list <string>.
*/
Const int WriteCsvData (LPCTSTR lpszFilename, const vector <list <string> & vlStr );
Private:
/// Determine whether the file is a CSV file
Const bool IsCsvFile (LPCTSTR lpszFilename );
};
# Endif
XCFileStream. cpp
/// Hide dependent files
/// C System File
/// C ++ System File
# Include <fstream> // read the ing File
# Include <algorithm>
/// Other library header files
/// This project header file
# Include "XCFileStream. h"
CXCFileStream: CXCFileStream ()
{
}
CXCFileStream ::~ CXCFileStream (void)
{
}
Const bool CXCFileStream: IsCsvFile (LPCTSTR lpszFilename)
{
/// 0. Determine whether the file name is valid
If (NULL = lpszFilename | 4> strlen (lpszFilename ))
Return false;
/// Local variable
String _ strFileName (lpszFilename );
Size_t _ iLen = _ strFileName. length ();
String _ strSuff (_ strFileName. substr (_ iLen-4, 4 ));
/// Convert to lowercase. If you want to convert to uppercase: tolower-> toupper.
Transform (_ strSuff. begin (), _ strSuff. end (), _ strSuff. begin (), tolower );
/// 1. Determine whether the file is a CSV file
Return (0 = _ strSuff. compare (". csv "));
}
Const int CXCFileStream: ReadCsvData (LPCTSTR lpszFilename, vector <list <string> & vlStr)
{
/// 1. Determine whether the file is a CSV file
If (! IsCsvFile (lpszFilename ))
Return XC_ERR_INVALID_FILE_NAME;
/// 2. Open the CSV file
Ifstream _ streamFromFile (lpszFilename );
/// Determine whether the file is successfully opened
If (NULL = _ streamFromFile)
Return (-errno );
/// Store the Read File Content
String _ strIn ("");
/// 3. Read a row
While (getline (_ streamFromFile, _ strIn )){
/// Source string of each line
LPCTSTR _ pcSrc = _ strIn. c_str ();
/// Store a row ',' to separate the parsed Elements
List <string> _ ltStr;
/// Parse values in this line
While (* _ pcSrc! = '\ 0 '){
/// String to hold this value
String _ strElem ("");
/// Analyze each character
If (* _ pcSrc = '"'){
/// Bump past opening quote
_ PcSrc ++;
/// Parse quoted value
While (* _ pcSrc! = '\ 0 '){
/// Test for quote character
If (* _ pcSrc = '"'){
/// Found one quote
_ PcSrc ++;
// If pair of quotes, keep one
// Else interpret as end of value
If (* _ pcSrc! = '"'){
_ PcSrc ++;
Break;
}
}
/// Add this character to value
_ StrElem. push_back (* _ pcSrc ++ );
}
}
Else {
// Parse unquoted value
While (* _ pcSrc! = '\ 0' & * _ pcSrc! = ',')
_ StrElem. push_back (* _ pcSrc ++ );
// Advance to next character (if not already end of string)
If (* _ pcSrc! = '\ 0 ')
_ PcSrc ++;
}
/// Add this string to container
_ LtStr. push_back (_ strElem );
}
/// Add the list of elements obtained from a row of file content after analysis to the container
VlStr. push_back (_ ltStr );
/// Return to zero to prevent the next Analysis of old data.
_ StrIn. assign ("");
}
Return XC_ERR_NONE;
}
Const int CXCFileStream: WriteCsvData (LPCTSTR lpszFilename, const vector <list <string> & vlStr)
{
/// 1. Determine whether the file is a CSV file
If (! IsCsvFile (lpszFilename ))
Return XC_ERR_INVALID_FILE_NAME;
/// 2. Open the CSV file
Ofstream _ streamToFile (lpszFilename );
/// Determine whether the file is successfully opened
If (NULL = _ streamToFile)
Return (-errno );
/// Local variable
Static TCHAR chQuote = '"';
Static TCHAR chComma = ',';
/// Loop through each list of string in vector
For (vector <list <string> >:: const_iterator vIt = vlStr. begin (); vIt! = VlStr. end (); vIt ++ ){
/// Loop through each string in list
For (list <string >:: const_iterator tables = vIt-> begin (); tables! = VIt-> end (); else ++ ){
/// Separate this value from previous
If (vIt-> begin ()! = Bytes)
_ StreamToFile. put (chComma );
/// Consider the possible string, or ", which requires special packaging.
Bool bComma = (bytes-> find (chComma )! = Pos-> npos );
Bool bQuote = (locate-> find (chQuote )! = Pos-> npos );
/// True or"
If (bComma | bQuote ){
_ StreamToFile. put (chQuote );
If (bQuote ){
For (string: const_iterator chIt = begin-> begin (); chIt! = Begin-> end (); chIt ++ ){
// Pairs of quotes interpreted as single quote
If (chQuote = * chIt)
_ StreamToFile. put (chQuote );
_ StreamToFile. put (* chIt );
}
}
Else
_ StreamToFile <* optional;
_ StreamToFile. put (chQuote );
}
Else
_ StreamToFile <* optional;
}
/// Line feed
_ StreamToFile <endl;
}
///
Return XC_ERR_NONE;
}
If you have better suggestions or have problems, please contact me according to my contact information on the blog. Thank you for your support and help.