我有一个包含6列的表格,我有像这样的CSV导出,每行有6个条目
me;val1;val2;val3;val4;val5;
me;val1;val2;val3;val4;val5;
我需要阅读这些条目并将其插入SQLITE3数据库。所以为了解析我使用的CSV
void readcsv()
{
FILE* stream = fopen("input.csv", "r");
char line[1024];
while (fgets(line, 1024, stream))
{
char* tmp = strdup(line);
printf("Field 3 would be %s\n", getcsvfield(tmp, 3));
// NOTE strtok clobbers tmp
free(tmp);
}
}
//Used for parsing CSV
const char* getcsvfield(char* line, int num)
{
const char* tok;
for (tok = strtok(line, ";");
tok && *tok;
tok = strtok(NULL, ";\n"))
{
if (!--num)
return tok;
}
return NULL;
}
所以我必须在插入查询中一次又一次地调用getcsvfield(tmp,fieldnumber),或者是否有更清洁有效的方式。
execute("INSERT INTO table(a,b,c,d,e,f) VALUES('%s','%s','%s');",getcsvfield(tmp, 1),getcsvfield(tmp, 2),....... and so on
请告知。
答案 0 :(得分:0)
更有效的方法是解析一次行,创建一个指向令牌的指针数组。然后,您可以将数组条目传递给execute
函数,如下所示
execute("INSERT INTO table(a,b,c,d,e,f) VALUES('%s','%s','%s');",token[0],token[1],...
这是一个从文件中读取行,将行拆分为标记,然后打印标记的示例。
#include <stdio.h>
#include <string.h>
int getTokens( char *line, char *token[], int maxt )
{
int i;
char *ptr = strtok(line, ";\n");
for ( i = 0; i < maxt; i++ )
{
if ( ptr == NULL )
return i;
token[i] = ptr;
ptr = strtok( NULL, ";\n" );
}
return i;
}
int main( void )
{
const int maxt = 6;
char line[1024];
char *token[maxt];
FILE *fp;
if ( (fp = fopen( "input.csv", "r" )) == NULL )
return 1;
while ( fgets(line, sizeof line, fp) != NULL )
{
int count = getTokens( line, token, maxt );
for ( int i = 0; i < count; i++ )
printf( "%d: '%s'\n", i, token[i] );
printf( "\n" );
}
fclose( fp );
}