• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            csv解析器

            頭文件:
            #ifndef __ClientModule_CSVFile_H__  
            #define __ClientModule_CSVFile_H__  


            #include 
            <fstream>  
            #include 
            <string>  
            #include 
            <sstream>  
            #include 
            <vector>
            #include 
            <iostream>

            typedef std::
            string String;


            /** CSV文件解析器
            * CSV逗號分隔值文件(Comma Separated value)規(guī)則
            * 1 開頭是不留空,以行為單位。
            * 2 可含或不含列名,含列名則居文件第一行。
            * 3 一行數(shù)據(jù)不垮行,無空行。
            * 4 以半角符號,作分隔符,列為空也要表達其存在。
            * 5 列內(nèi)容如存在半角逗號(即,)則用半角引號(即"")將該字段值包含起來。
            * 6 列內(nèi)容如存在半角引號(即")則應(yīng)替換成半角雙引號("")轉(zhuǎn)義。
            * 7 文件讀寫時引號,逗號操作規(guī)則互逆。
            * 8 內(nèi)碼格式不限,可為ASCII、Unicode或者其他。
            */

            class CSVFile
            {
            public:
                CSVFile();
                
            ~CSVFile();

            public:
                
            /// 打開CSV文件
                
            /// @param[in] strFilename 文件名

                bool open(const char* strFilePath);  

                
            /// 另存為CSV文件
                bool save(const char* strFilePath);

                
            /// 保存已經(jīng)打開的CSV文件
                bool save();

                
            /// 是否已經(jīng)打開有文件
                bool isOpen();

                
            /// 根據(jù)列名獲得到列索引
                int getFieldIndex(const char* fieldName);

                
            /// 獲取列數(shù)
                int getColumnSize() return mColumnCount; }

                
            /// 獲取行數(shù)
                int getRowSize() return (int)mTable.size(); }

                
            /// 是否使用UTF8編碼
                void setUTF8(bool bUtf8);

            public:
                
            /// 讀取數(shù)據(jù)
                
            /// @param[in] row 第幾行
                
            /// @param[in] column 第幾列

                template<class T>  
                    T Read(
            const int row, const int column)  
                
            {
                    
            //printf("CSVFile::Read(%d, %d)\n", row, column);

                    
            // 獲取行
                    int rowIndex = row - 1;
                    
            if (row<1 || row>(int)mTable.size())
                    
            {
                        printf(
            "CSVFile::Read() CANNOT GET ROW[%d]!\n", row);
                        
            return T();
                    }

                    Field
            & filed = mTable[rowIndex];

                    
            // 獲取列
                    int columnIndex = column - 1;
                    
            if (column<1 || column>(int)filed.size())
                    
            {
                        printf(
            "CSVFile::Read() CANNOT GET COLUMN[%d]!\n", column); 
                        
            return T();
                    }

                    std::
            string& strData = filed[columnIndex];

                    
            // 獲取數(shù)據(jù)
                    T data;
                    std::stringstream ss;
                    ss 
            << strData;
                    ss 
            >> data;
                    
            return data;
                }


                String readString(
            const int row, const int column)  
                
            {
                    
            // 獲取行
                    int rowIndex = row - 1;
                    
            if (rowIndex<0 || rowIndex>(int)mTable.size()-1)
                    
            {
                        printf(
            "CSVFile::readString() CANNOT GET ROW[%d]!\n", row);
                        
            return String();
                    }

                    Field
            & filed = mTable[rowIndex];

                    
            // 獲取列
                    int columnIndex = column - 1;
                    
            if (column<1 || column>(int)filed.size())
                    
            {
                        printf(
            "CSVFile::readString() CANNOT GET COLUMN[%d]!\n", column); 
                        
            return String();
                    }

                    String
            & strData = filed[columnIndex];

                    
            // 獲取數(shù)據(jù)
                    return strData;
                }


                
            /// 讀取數(shù)據(jù)
                
            /// @param[in] row 第幾行
                
            /// @param[in] column 第幾列
                
            /// @param[in] data 寫入的數(shù)據(jù)

                template<class T>  
                    
            bool Write(const int row, const int column, T data)  
                
            {
                    
            //printf("CSVFile::Write(%d, %d)\n", row, column);

                    
            int rowIndex = row - 1;
                    
            if (rowIndex < 0)
                    
            {
                        
            // 如果索引號為負數(shù),則增長一行。
                        mTable.push_back(Field());
                        rowIndex 
            = (int)mTable.size() - 1;
                    }

                    
            else
                    
            {
                        
            // 行數(shù)不夠,自動增長。
                        while ((int)mTable.size()<row)
                        
            {
                            mTable.push_back(Field());
                        }

                    }

                    Field
            & filed = mTable[rowIndex];

                    
            int columnIndex = column - 1;
                    
            if (columnIndex < 0)
                    
            {
                        
            // 如果索引號為負數(shù),則增長一列。
                        printf("CSVFile::Write() row number is error!\n");
                        
            return false;
                    }

                    
            else
                    
            {
                        
            // 列數(shù)不夠,自動增長。
                        while ((int)filed.size()<column)
                        
            {
                            filed.push_back(std::
            string());
                        }

                    }

                    std::
            string& strData = filed[columnIndex];

                    
            // 寫入數(shù)據(jù)
                    std::stringstream ss;  
                    ss 
            << data;  
                    strData 
            = ss.str();  

                    
            return true;
                }


                
            /// 讀取數(shù)據(jù)
                
            /// @param[in] cell 列數(shù)
                
            /// @param[in] data 寫入的數(shù)據(jù)

                template<class T>  
                    
            bool Push(const int cell, const T& data)  
                
            {
                    
            return true;
                }


                
            /// 刪除一行
                bool deleteRow(const int row);

                
            /// 刪除所有行
                bool deleteAllRow();

            private:  
                typedef std::vector
            <std::string> Field; 
                typedef std::vector
            <Field> Table;

                
            /// 讀取一行數(shù)據(jù)
                void readLine(Field& field);

                
            /// 寫入一行
                void writeLine(const Field& field);

                
            /// 解析整個文本
                bool parse();

                
            /// 解析一行數(shù)據(jù)
                void parseLine(const char* strLine, int nSize, Field& result);
                
            void parseLine(const std::string& strLine, Field& result);

                
            /// 寫入一行
                void writeLine(std::fstream& file, const Field& field);

                
            /// 讀取一行數(shù)據(jù)
                void readLine(std::fstream& file, Field& field);

            private:  
                std::fstream    mFile;            
            ///< 文件流
                String            mFilePath;        ///< 文件路徑

                Table            mTable;            ///< 表
                Field            mHead;            ///< 表頭
                String            mLine;            ///< 一行字符串,沒有解析的

                int                mRowCount;        ///< 行數(shù)
                int                mColumnCount;    ///< 列數(shù)

                bool            m_bUtf8;        ///< UTF8編碼
            };  



            #endif // __CSVFile_H__ 

            源文件:
            #include "stdafx.h"
            #include
            "CSVFile.h"
            #include
            <sstream>
            #include
            <assert.h>
            #include
            <iostream>
            #include
            <stdio.h>
            #include
            "FileUtility.h"
            #include
            "StringUtility.h"


            #pragma warning(disable:
            4996)

            /* Character values */
            const char CSV_TAB = 0x09; ///< Tab
            const char CSV_SPACE = 0x20; ///< 空白符
            const char CSV_CR = 0x0d; ///< 回車符\r
            const char CSV_LF = 0x0a; ///< 換行符\n
            const char CSV_COMMA = ','; ///< 逗號,
            const char CSV_SINGLE_QUOTE = '\''; ///< 單引號'
            const char CSV_DOUBLE_QUOTE = '\"'; ///< 雙引號“

            namespace detail
            {
            int replace(String& src_str, const String& old_str, const String& new_str)
            {
            int count = 0;
            int old_str_len = int(old_str.length());
            int new_str_len = int(new_str.length());
            int pos = 0;
            while((pos=int(src_str.find(old_str,pos)))!=String::npos)
            {
            src_str.replace(pos,old_str_len,new_str);
            pos
            +=new_str_len;
            ++count;
            }

            return count;
            }

            }


            CSVFile::CSVFile()
            : mRowCount(
            0)
            , mColumnCount(
            0)
            , m_bUtf8(
            false)
            {

            }


            CSVFile::
            ~CSVFile()
            {
            mFile.close();
            }


            bool CSVFile::open(const char* strFilePath)
            {
            // 檢查傳入的參數(shù)
            if (strFilePath == 0) return false;
            printf(
            "begin open csv file: [%s]\n", strFilePath);

            // 檢查文件是否存在
            if ( !FileUtility::fileExist(strFilePath) )
            {
            // 創(chuàng)建可讀可寫文件
            FILE* f = fopen(strFilePath, "w+");
            fclose(f);
            }


            // 關(guān)閉已經(jīng)打開的
            if (mFile.is_open())
            {
            mFile.close();
            //關(guān)閉文件
            mFile.clear();//清除狀態(tài)
            }


            // 打開文件
            mFile.open(strFilePath, std::ios_base::in | std::ios_base::out);
            if (!mFile.is_open())
            {
            goto FAILED;
            }

            printf(
            "Open csv file OK: [%s]\n", strFilePath);
            mFilePath
            = strFilePath;

            // 清空數(shù)據(jù)
            mTable.clear();

            // 解析文件
            return parse();

            FAILED:
            printf(
            "open csv file FAILED!: [%s]\n", strFilePath);
            return false;
            }


            bool CSVFile::save( const char* strFilePath )
            {
            std::fstream file(strFilePath, std::ios_base::
            out);

            if (!file.is_open()) return false;

            Table::iterator iter
            = mTable.begin();
            Table::iterator iEnd
            = mTable.end();
            for (;iter!=iEnd; ++iter)
            {
            Field
            & field = *iter;
            writeLine(file, field);
            }

            file.close();
            printf(
            "save as cvs file: [%s] SUCCESS!\n", strFilePath );

            return true;
            }


            bool CSVFile::save()
            {
            return save(mFilePath.c_str());
            }


            bool CSVFile::parse()
            {
            int nRowCount = 0;
            int nCellCount = 0;
            while (!mFile.eof())
            {
            mTable.push_back(Field());
            Field
            & field = mTable.back();
            readLine(field);
            if (field.empty()) { mTable.pop_back(); continue; }
            if ((int)field.size()>nCellCount) nCellCount = (int)field.size();
            ++nRowCount;
            if (nRowCount==1) mHead = field;
            }

            mRowCount
            = nRowCount;
            mColumnCount
            = nCellCount;
            return true;
            }


            void CSVFile::parseLine( const String& strLine, Field& result )
            {
            return parseLine(strLine.c_str(), (int)strLine.size(), result);
            }


            void CSVFile::parseLine(const char* strLine, int nSize, Field& result)
            {
            if (strLine==0) return;

            result.clear();

            bool bIsInWord = false;
            bool bIsHaveSpace = false;
            String strCurWorld;

            for (int i=0; i<nSize; i++)
            {
            const char& ch = strLine[i];
            if (ch == '\0')
            {
            if (i >= 1 && strLine[i-1] == CSV_COMMA)
            {
            strCurWorld
            = CSV_SPACE;
            }

            break;
            }


            bool bIsAdd = true;

            switch (ch)
            {
            // 逗號
            case CSV_COMMA:
            {
            if (!bIsInWord)
            {
            // 一項結(jié)束
            result.push_back(strCurWorld);

            bIsInWord
            = false;
            bIsHaveSpace
            = false;
            strCurWorld
            = "";
            bIsAdd
            = false;
            }

            }

            break;

            // 雙引號
            case CSV_DOUBLE_QUOTE:
            {
            if (!bIsInWord)
            {
            bIsInWord
            = true;
            bIsHaveSpace
            = true;
            bIsAdd
            = false;
            }

            else
            {
            if (CSV_DOUBLE_QUOTE == strLine[i+1])
            {
            i
            ++;
            }

            else if (bIsHaveSpace)
            {
            bIsInWord
            = false;
            bIsAdd
            = false;
            }

            else
            {
            assert(
            0);
            }


            }

            }

            break;
            default:
            //bIsInWord = true;
            break;
            }
            ;

            if (bIsAdd)
            {
            strCurWorld
            += ch;
            }


            }


            if (!strCurWorld.empty())
            {
            result.push_back(strCurWorld);
            }

            }


            void CSVFile::readLine( Field& field )
            {
            readLine(mFile, field);
            }


            void CSVFile::readLine( std::fstream& file, Field& field )
            {
            // 讀取一行
            std::getline(file, mLine, '\n');
            if (mLine.empty()) return;

            // 轉(zhuǎn)換編碼
            if (m_bUtf8)
            {
            StringUtility::UTF8ToAnsi(mLine, mLine);
            }


            // 解析數(shù)據(jù)
            parseLine(mLine.c_str(), (int)mLine.size(), field);
            }


            void CSVFile::writeLine( const Field& field )
            {
            writeLine(mFile, field);
            }


            void CSVFile::writeLine( std::fstream& file, const Field& field )
            {
            Field::const_iterator iter
            =field.begin();
            Field::const_iterator iEnd
            =field.end();
            for (; iter!=iEnd; ++iter)
            {
            String str
            = *iter;
            detail::replace(str,
            "\"", "\"\"");

            // 轉(zhuǎn)碼
            if (m_bUtf8)
            {
            StringUtility::AnsiToUTF8(str, str);
            }


            // 寫入內(nèi)容
            if (str.find_first_of(CSV_COMMA) != String::npos)
            {
            // 塞兩個雙引號
            file << CSV_DOUBLE_QUOTE << str << CSV_DOUBLE_QUOTE;
            }

            else
            {
            file
            << str;
            }

            if ( (iter + 1) != iEnd) file << CSV_COMMA; // 寫入逗號
            }

            file
            << std::endl;
            }


            int CSVFile::getFieldIndex( const char* fieldName )
            {
            if (fieldName==0) return -1;

            Field::const_iterator iter
            = mHead.begin();
            Field::const_iterator iEnd
            = mHead.end();
            for (; iter!=iEnd; ++iter)
            {
            if (*iter == fieldName)
            {
            return int(iter - mHead.begin());
            }

            }


            return -1;
            }


            bool CSVFile::deleteRow( const int row )
            {
            int index = row - 1;
            if (index<0 || index>=(int)mTable.size()) return false;
            mTable.erase(mTable.begin()
            +index);
            return true;
            }


            bool CSVFile::deleteAllRow()
            {
            mRowCount
            = 0;
            mColumnCount
            = 0;
            mTable.clear();
            return true;
            }


            bool CSVFile::isOpen()
            {
            return mFile.is_open();
            }


            void CSVFile::setUTF8( bool bUtf8 )
            {
            m_bUtf8
            = bUtf8;
            }


            讀取示例:
            CSVFile csv;
            csv.open(
            "hello.csv");
            int n = csv.Read<int>(1, 1);
            std::
            string str = csv.Read<std::string>(1, 2);


            寫入示例:
            CSVFile csv;
            csv.deleteAllRow();
            csv.Write
            <int>(1, 1, 1);
            csv.Write
            <std::string>(1, 2, "hello");
            csv.save(
            "hello.csv");

            posted on 2011-06-28 17:54 楊粼波 閱讀(2000) 評論(1)  編輯 收藏 引用

            評論

            # re: csv解析器[未登錄] 2011-11-08 16:36 123

            12  回復(fù)  更多評論   


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久精品中文字幕一区| 久久人人爽人人爽人人片AV东京热 | 久久人与动人物a级毛片| 国产A三级久久精品| 久久精品桃花综合| 久久人人爽人人人人片av| 久久99精品国产99久久6男男| 国产99久久精品一区二区| 国产精品岛国久久久久| 欧美与黑人午夜性猛交久久久| 午夜精品久久久久久久无码| jizzjizz国产精品久久| 91精品国产高清久久久久久91 | 亚洲中文字幕久久精品无码喷水| 久久精品免费观看| 国色天香久久久久久久小说| 久久久91人妻无码精品蜜桃HD| 精品国产乱码久久久久久郑州公司 | 久久噜噜电影你懂的| 国产精品激情综合久久| 国产精品激情综合久久| 99久久精品日本一区二区免费| 综合久久国产九一剧情麻豆| 日韩va亚洲va欧美va久久| 青青草原综合久久大伊人精品| 精品无码久久久久久尤物| 狠狠色婷婷久久综合频道日韩| 欧美精品一区二区久久| 亚洲精品美女久久777777| 午夜不卡888久久| 精品久久久久久国产潘金莲| 久久综合狠狠综合久久综合88| 草草久久久无码国产专区| 久久久久人妻一区精品性色av| 久久久精品视频免费观看| 欧美激情精品久久久久| 久久国产精品99精品国产987| AV无码久久久久不卡蜜桃| 国产Av激情久久无码天堂| 久久精品aⅴ无码中文字字幕重口| 亚洲综合伊人久久大杳蕉|