Chinaunix首页 | 论坛 | 博客
  • 博客访问: 560434
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2356
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-26 16:13:16

简单的用EXCEL对照测试过

#include
#include
#include

template bool csvread( const char* filename, callbackfun cbf, char delimit=',' )
{
    std::ifstream file( filename, std::ios::binary );
    if( !file ) return false; // 文件打开失败

    bool quo = false; // 此字段是否以双引号开始
    bool quopre = false; // 当此字段以双引号开始时,前一个是否为双引号
    std::string val;
    size_t row=0, col=0;

    for( char c; file.get(c); )
    {
        if( c == delimit )
        {
            if( quo && !quopre )
            {
                val += c;
            }
            else
            {
                if( !cbf(row,col,val) )
                    return false;
                quo = false;
                quopre = false;
                val.clear();
                ++col;
            }
        }
        else switch( c )
        {
        case '"':
            if( !quo )
            {
                if( val.empty() )
                    quo = true;
                else
                    val += c;
            }
            else if( quopre )
            {
                quopre = false;
                val += c;
            }
            else
                quopre = true;
            break;
        case '\r':
            break;
        case '\n':
            if( quo )
            {
                val += c;
            }
            else
            {
                if( !cbf(row,col,val) )
                    return false;
                quo = false;
                quopre = false;
                val.clear();
                ++row;
                col = 0;
            }
            break;
        default:
            if( quopre )
            {
                quo = false;
                quopre = false;
            }
            val += c;
            break;
        }
    }

    if( !val.empty() || col!=0 )
    {
        if( !cbf(row,col,val) )
            return false;
    }

    return file.eof();
}

void csvvalue( const char* str, std::string& val )
{
    if( str[strcspn(str,",\"\n")] == '\0' )
    {
        val.clear();
        return;
    }

    // 如果有 逗号 分号 换行,则用引号括起来,并把其中原有的引号变为双份
    val = '"';
    const char* p1 = str;
    for( const char* p2; (p2=strchr(p1,'"'))!=0; p1=p2+1 )
    {
        val.append( p1, p2-p1+1 );
        val.append( 1, '"' );
    }
    val.append( p1 );
    val.append( 1, '"' );

    return;
}

//////////////////// 以下为测试 ////////////////////

#include
#include
using namespace std;

struct foo
{
    foo() : row(0), col(0)
    {
    }

    size_t row, col;

    bool operator()( size_t r, size_t c, std::string val )
    {
        if( r != row )
            cout << '\n';
        if( c != 0 )
            cout << '|';
        cout << val;
        row=r, col=c;

        return true;
    }
};

int main()
{
    // 否则打开含中文的路径失败,但可惜的是MinGW用之无效,又不支持"chs"
    std::locale loc = std::locale::global( std::locale(std::locale(),"",std::locale::ctype) );
   
    csvread( "C:\\Documents and Settings\\0846\\桌面", foo() );

    std::string val;
    csvvalue( "\"a\"\"b\"\"", val );

    return 0;
}

 

阅读(4457) | 评论(0) | 转发(0) |
0

上一篇:读取Princeton Instruments公司的SPE格式图像

下一篇:没有了

给主人留下些什么吧!~~