简单便捷的CSV文件解析函数

#include <string>
#include <list>

typedef std::list<std::string> CSVRecord;

size_t ReadFieldValue(const std::string& str, size_t pos, const char* pszSeparator, std::string& strFieldValue)
{
    // 清空字段值
    strFieldValue = "";
	
    // 分隔字符序列为空
    if ( NULL == pszSeparator )
    {
        // 返回无效字符索引
        return std::string::npos;
    }
	
    // 待查找字符串为空
    if ( str.empty() )
    {
        return std::string::npos;
    }
	
    // 跳过无效字符
    while ( (' ' == str[pos]) || ('\t' == str[pos]) )
    {
        ++pos;
    }
	
    // 查找字符超出字符串边界
    if ( '\0' == str[pos] )
    {
        return std::string::npos;
    }
	
    size_t found = str.find_first_of(pszSeparator, pos);
    if ( pos == found )
    {
        return found;
    }
    else if ( std::string::npos != found )
    {
        // 效率比substr要快很多
        strFieldValue.assign((str.begin() + pos), (str.begin() + found));
        return found;
    }
    else
    {
        strFieldValue.assign((str.begin() + pos), str.end());
        return std::string::npos;
    }
}

bool ParseCSVLine(const std::string str, const char* pszSeparator, CSVRecord& oRecord)
{
	oRecord.clear();

	if ( str.empty() || !pszSeparator)
	{
		return false;
	}

	std::string strFieldValue;
	size_t found = ReadFieldValue(str, 0, pszSeparator, strFieldValue);
	while ( std::string::npos != found )
	{
		oRecord.push_back(strFieldValue);	
		found = ReadFieldValue(str, found + 1, pszSeparator, strFieldValue);
	}

	return true;
}

int main(int argc, char* argv[])
{
	std::string strTest = "abc'1111,gef,dhk,,1111";
	CSVRecord oRecord;
	ParseCSVLine(strTest, ",'", oRecord);
		
	return 0;
}
posted on 2011-05-29 07:16  潇湘雨歇  阅读(408)  评论(0编辑  收藏  举报