作者:手机用户2602927807 | 来源:互联网 | 2024-12-05 20:06
#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 <<&#8216;\n&#8217;;
if( c != 0 )
cout <<&#8216;|&#8217;;
cout < row=r, col=c;
return true;
}
};
int main()
{
// 否则打开含中文的路径失败,但可惜的是MinGW用之无效,又不支持&#8221;chs&#8221;
std::locale loc = std::locale::global( std::locale(std::locale(),&#8221;&#8221;,std::locale::ctype) );
csvread( &#8220;C:\\Documents and Settings\\0846\\桌面\\Book1.csv&#8221;, foo() );
std::string val;
csvvalue( &#8220;\&#8221;a\&#8221;\&#8221;b\&#8221;\&#8221;&#8221;, val );
return 0;
}