2012年(158)
分类: C/C++
2012-11-26 16:13:16
简单的用EXCEL对照测试过
#include
#include
#include
template
{
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;
}