C 我应该如何将文件中的令牌解析为结构?
我需要将csv文件直接解析为结构。假设csv文件是这样的:C 我应该如何将文件中的令牌解析为结构?,c,file,csv,parsing,struct,C,File,Csv,Parsing,Struct,我需要将csv文件直接解析为结构。假设csv文件是这样的: Codice identificativo;Nome;Produttore;Categoria;Prezzo;Eta' minima; 214950;Total War: ROME II;Creative Assembly;Manageriale;54,99;16; 231140;Cities XL Platinum;Focus Home Interactive;Manageriale;14,99;3; 242700;Injustic
Codice identificativo;Nome;Produttore;Categoria;Prezzo;Eta' minima;
214950;Total War: ROME II;Creative Assembly;Manageriale;54,99;16;
231140;Cities XL Platinum;Focus Home Interactive;Manageriale;14,99;3;
242700;Injustice: Gods Among Us;NetherRealm Studios;Picchiaduro;19,99;16;
244210;Assetto Corsa;Kunos Simulazioni;Racing;29,99;3;
...
我写了这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
...
typedef struct {
char codice [6];
char nome [20];
char produttore [20];
char categoria [15];
float prezzo;
int eta_min;
} Gioco;
...
int main() {
int max=1, s=0, k=0, n=0;
Utente registr [max];
Gioco database [30];
char cwd[1024], riga [120];
char* token=NULL;
FILE* sorgente;
if ((sorgente=fopen("Database_Videogames.csv", "r"))==NULL) {
printf ("----------------------------------------- Database_Videogames.csv non trovato! -----------------------------------------\n\n");
if (getcwd(cwd, sizeof(cwd))!=NULL) {
printf("%*sPer caricare il file Database_Videogames.csv, inserirlo nella seguente cartella: %s.\n\n", 26, "", cwd);
}
}
else {
printf ("------------------------------------------- Database_Videogames.csv trovato! -------------------------------------------\n");
while(fgets(riga, sizeof (riga), sorgente)) {
token=strtok(riga, ";");
strcpy(database[n].codice,token);
printf("%s\n",database[n].codice);
token=strtok(NULL, ";");
strcpy(database[n].nome,token);
printf("%s\n",database[n].nome);
token=strtok(NULL, ";");
strcpy(database[n].produttore,token);
printf("%s\n",database[n].produttore);
token=strtok(NULL, ";");
strcpy(database[n].categoria,token);
printf("%s\n",database[n].categoria);
token=strtok(NULL, ";");
database[n].prezzo=atof(token);
printf("%f\n",database[n].prezzo);
token=strtok(NULL, ";\n");
database[n].eta_min=atoi(token);
printf("%d\n",database[n].eta_min);
n++;
}
fclose(sorgente);
printf("\n\n\n");
...
此外,我根本不想读取文件的第一行,我是否应该使用for循环来执行此操作?您可以使用token=strtok(riga,“\n”)重复中断每一行;然后再重复一次,以打断“;”之间的所有信息标记=strtok(NULL,“;”) 问题的主要原因是某些字段没有足够的内存,这将在使用
strcpy
时导致问题。使用strncpy
防止出现这种情况。此代码还测试每个字段是否有足够的空间。可以使用
strtok
,但如果可能存在连续分隔符,最好使用其他分隔符,例如strpbrk
使用
strpbrk
和两个指针可以遍历文件的每一行并提取每个字段。如果未找到分隔符,srtpbrk
将返回NULL。这个问题可以通过多种方式解决。这只是继续循环,忽略文本的问题行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct {
char codice [10];
char nome [30];
char produttore [30];
char categoria [30];
float prezzo;
int eta_min;
} Gioco;
int main(void) {
int n=0;
int each=0;
int span=0;
Gioco database [30];
char cwd[1024], riga [120];
char* start = NULL;
char* end = NULL;
char* comma = NULL;
FILE* sorgente;
if ((sorgente=fopen("Database_Videogames.csv", "r"))==NULL) {
printf ("----------------------------------------- Database_Videogames.csv non trovato! -----------------------------------------\n\n");
if (getcwd(cwd, sizeof(cwd))!=NULL) {
printf("%*sPer caricare il file Database_Videogames.csv, inserirlo nella seguente cartella: %s.\n\n", 26, "", cwd);
}
}
else {
printf ("------------------------------------------- Database_Videogames.csv trovato! -------------------------------------------\n");
fgets(riga, sizeof (riga), sorgente);//read first line and ignore
while(fgets(riga, sizeof (riga), sorgente)) {
start = riga;
end = strpbrk ( start, ";");//find the next ;
if ( !end) {
continue;//handle the problem
}
span = ( end - start);//get span of characters between ;
if ( span > sizeof ( database[n].codice)) {
span = sizeof ( database[n].codice);//make sure not to exceed size of array
}
strncpy ( database[n].codice, start, span);
database[n].codice[span] = '\0';
start = end + 1;
end = strpbrk ( start, ";");//find the next ;
if ( !end) {
continue;//handle the problem
}
span = ( end - start);//get span of characters between ;
if ( span > sizeof ( database[n].nome)) {
span = sizeof ( database[n].nome);//make sure not to exceed size of array
}
strncpy ( database[n].nome, start, span);
database[n].nome[span] = '\0';
start = end + 1;
end = strpbrk ( start, ";");//find the next ;
if ( !end) {
continue;//handle the problem
}
span = ( end - start);//get span of characters between ;
if ( span > sizeof ( database[n].produttore)) {
span = sizeof ( database[n].produttore);//make sure not to exceed size of array
}
strncpy ( database[n].produttore, start, span);
database[n].produttore[span] = '\0';
start = end + 1;
end = strpbrk ( start, ";");//find the next ;
if ( !end) {
continue;//handle the problem
}
span = ( end - start);//get span of characters between ;
if ( span > sizeof ( database[n].categoria)) {
span = sizeof ( database[n].categoria);//make sure not to exceed size of array
}
strncpy ( database[n].categoria, start, span);
database[n].categoria[span] = '\0';
start = end + 1;
end = strpbrk ( start, ";\n");//find the next ; or \n
if ( !end) {
continue;//handle the problem
}
comma = strpbrk ( start, ",");//find a comma
if ( comma && comma < end) {
*comma = '.';//change comma to dot
}
database[n].prezzo = 0.0f;
database[n].eta_min = 0;
if ( EOF == sscanf ( start, "%f%n", &database[n].prezzo, &span)) {
break;//handle the problem
}
start = end + 1;
if ( EOF == sscanf ( start, "%d%n", &database[n].eta_min, &span)) {
break;//handle the problem
}
n++;
if ( n >= 30) {
break;
}
}
fclose(sorgente);
printf("\n\n\n");
}
while ( each < n) {
printf ( "n %d\n codice %s\n nome %s\n produttore %s\n categoria %s\n prezzo %f\n eta_min %d\n"
, each
, database[each].codice
, database[each].nome
, database[each].produttore
, database[each].categoria
, database[each].prezzo
, database[each].eta_min);
each++;
}
return 0;
}
#包括
#包括
#包括
#包括
类型定义结构{
炭尾[10];
char-nome[30];
char-produttore[30];
字符分类[30];
浮子前奏曲;
内塔乌敏;
}Gioco;
内部主(空){
int n=0;
int各=0;
int span=0;
Gioco数据库[30];
char-cwd[1024],riga[120];
char*start=NULL;
char*end=NULL;
字符*逗号=空;
文件*sorgente;
if((sorgente=fopen(“Database_Videogames.csv”,“r”))==NULL){
printf(“---------------------------------------数据库\u Videogames.csv非trovato!---------------------------------------\n\n”);
if(getcwd(cwd,sizeof(cwd))!=NULL){
printf(“%*sPer caricare il file Database\u Videogames.csv,inserirlo nella segunte cartella:%s.\n\n”,26“,cwd);
}
}
否则{
printf(“---------------------------------------Database\u Videogames.csv trovato!---------------------------------------\n”);
fgets(riga,sizeof(riga),sorgente);//读取第一行并忽略
而(fgets(里加,里加,索伦特)){
开始=里加;
end=strpbrk(start,“;”;//查找下一个;
如果(!结束){
continue;//处理这个问题
}
span=(end-start);//获取之间的字符范围;
if(span>sizeof(数据库[n].codice)){
span=sizeof(数据库[n].codice);//确保不超过数组的大小
}
strncpy(数据库[n].codice,start,span);
数据库[n]。密码[span]='\0';
开始=结束+1;
end=strpbrk(start,“;”;//查找下一个;
如果(!结束){
continue;//处理这个问题
}
span=(end-start);//获取之间的字符范围;
if(span>sizeof(数据库[n].nome)){
span=sizeof(数据库[n].nome);//确保不超过数组的大小
}
strncpy(数据库[n].nome,start,span);
数据库[n].nome[span]='\0';
开始=结束+1;
end=strpbrk(start,“;”;//查找下一个;
如果(!结束){
continue;//处理这个问题
}
span=(end-start);//获取之间的字符范围;
if(span>sizeof(数据库[n].produttore)){
span=sizeof(数据库[n].produttore);//确保不超过数组的大小
}
strncpy(数据库[n].produttore,start,span);
数据库[n]。产品按钮[span]='\0';
开始=结束+1;
end=strpbrk(start,“;”;//查找下一个;
如果(!结束){
continue;//处理这个问题
}
span=(end-start);//获取之间的字符范围;
if(span>sizeof(数据库[n].categoria)){
span=sizeof(数据库[n].categoria);//确保不超过数组的大小
}
strncpy(数据库[n].categoria,start,span);
数据库[n]。分类[span]='\0';
开始=结束+1;
end=strpbrk(start,;\n”);//查找下一个;或\n
如果(!结束){
continue;//处理这个问题
}
逗号=strpbrk(开始,“”;//查找逗号
if(逗号和逗号<结束){
*逗号='。;//将逗号更改为点
}
数据库[n]。prezzo=0.0f;
数据库[n]。eta_min=0;
如果(EOF==sscanf(开始,“%f%n”,&database[n].prezzo,&span)){
break;//处理这个问题
}
开始=结束+1;
如果(EOF==sscanf(开始、%d%n、&database[n].eta_min、&span)){
break;//处理这个问题
}
n++;
如果(n>=30){
打破
}
}
fclose(sorgente);
printf(“\n\n\n”);
}
while(每个
这里有一个使用注释的选项
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct {
char codice [10];
char nome [30];
char produttore [30];
char categoria [30];
float prezzo;
int eta_min;
} Gioco;
char *extractstr ( char * source, char *target, int max);
char *extractfloat ( char * source, float *targetfloat);
char *extractint ( char * source, int *targetint);
int main(void) {
int n=0;
int each=0;
Gioco database [30];
char cwd[1024], riga [120];
char* start = NULL;
FILE* sorgente;
if ((sorgente=fopen("Database_Videogames.csv", "r"))==NULL) {
printf ("----------------------------------------- Database_Videogames.csv non trovato! -----------------------------------------\n\n");
if (getcwd(cwd, sizeof(cwd))!=NULL) {
printf("%*sPer caricare il file Database_Videogames.csv, inserirlo nella seguente cartella: %s.\n\n", 26, "", cwd);
}
}
else {
printf ("------------------------------------------- Database_Videogames.csv trovato! -------------------------------------------\n");
fgets(riga, sizeof (riga), sorgente);//read first line and ignore
while(fgets(riga, sizeof (riga), sorgente)) {
start = riga;
start = extractstr ( start, database[n].codice, sizeof ( database[n].codice));
if ( !( *start)) {
continue;//handle the problem
}
start = extractstr ( start, database[n].nome, sizeof ( database[n].nome));
if ( !( *start)) {
continue;//handle the problem
}
start = extractstr ( start, database[n].produttore, sizeof ( database[n].produttore));
if ( !( *start)) {
continue;//handle the problem
}
start = extractstr ( start, database[n].categoria, sizeof ( database[n].categoria));
if ( !( *start)) {
continue;//handle the problem
}
start = extractfloat ( start, &database[n].prezzo);
if ( !( *start)) {
continue;//handle the problem
}
start = extractint ( start, &database[n].eta_min);
n++;
if ( n >= 30) {
break;
}
}
fclose(sorgente);
printf("\n\n\n");
}
while ( each < n) {
printf ( "n %d\n codice %s\n nome %s\n produttore %s\n categoria %s\n prezzo %f\n eta_min %d\n"
, each
, database[each].codice
, database[each].nome
, database[each].produttore
, database[each].categoria
, database[each].prezzo
, database[each].eta_min);
each++;
}
return 0;
}
char *extractstr ( char * source, char *target, int max) {
char *semicolon = NULL;
int span = 0;
semicolon = strpbrk ( source, ";");//find the next ;
if ( !semicolon) {
return source + 1;//handle the problem
}
span = ( semicolon - source);//get span of characters between ;
if ( span > max) {
span = max;//make sure not to exceed size of array
}
strncpy ( target, source, span);
target[span] = '\0';
return semicolon + 1;
}
char *extractfloat ( char * source, float *targetfloat) {
char *semicolon = NULL;
char *comma = NULL;
semicolon = strpbrk ( source, ";");//find the next ;
if ( !semicolon) {
return source + 1;//handle the problem
}
comma = strpbrk ( source, ",");//find comma
if ( comma && comma < semicolon) {
*comma = '.';//change comma to dot
}
*targetfloat = 0.0f;
sscanf ( source, "%f", targetfloat);
return semicolon + 1;
}
char *extractint ( char * source, int *targetint) {
char *semicolon = NULL;
semicolon = strpbrk ( source, ";\n");//find the next ; or \n
if ( !semicolon) {
return source + 1;//handle the problem
}
*targetint = 0;
sscanf ( source, "%d", targetint);
return semicolon + 1;
}
#包括
#包括
#包括
#包括
类型定义结构{
炭尾[10];
char-nome[30];
char-produttore[30];
字符分类[30];
浮子前奏曲;
内塔乌敏;
}Gioco;
char*extractstr(char*source,char*target,int max);
char*extractfloat(char*source,float*targetfloat);
char*extractint(char*source,int*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct {
char codice [10];
char nome [30];
char produttore [30];
char categoria [30];
float prezzo;
int eta_min;
} Gioco;
char *extractstr ( char * source, char *target, int max);
char *extractfloat ( char * source, float *targetfloat);
char *extractint ( char * source, int *targetint);
int main(void) {
int n=0;
int each=0;
Gioco database [30];
char cwd[1024], riga [120];
char* start = NULL;
FILE* sorgente;
if ((sorgente=fopen("Database_Videogames.csv", "r"))==NULL) {
printf ("----------------------------------------- Database_Videogames.csv non trovato! -----------------------------------------\n\n");
if (getcwd(cwd, sizeof(cwd))!=NULL) {
printf("%*sPer caricare il file Database_Videogames.csv, inserirlo nella seguente cartella: %s.\n\n", 26, "", cwd);
}
}
else {
printf ("------------------------------------------- Database_Videogames.csv trovato! -------------------------------------------\n");
fgets(riga, sizeof (riga), sorgente);//read first line and ignore
while(fgets(riga, sizeof (riga), sorgente)) {
start = riga;
start = extractstr ( start, database[n].codice, sizeof ( database[n].codice));
if ( !( *start)) {
continue;//handle the problem
}
start = extractstr ( start, database[n].nome, sizeof ( database[n].nome));
if ( !( *start)) {
continue;//handle the problem
}
start = extractstr ( start, database[n].produttore, sizeof ( database[n].produttore));
if ( !( *start)) {
continue;//handle the problem
}
start = extractstr ( start, database[n].categoria, sizeof ( database[n].categoria));
if ( !( *start)) {
continue;//handle the problem
}
start = extractfloat ( start, &database[n].prezzo);
if ( !( *start)) {
continue;//handle the problem
}
start = extractint ( start, &database[n].eta_min);
n++;
if ( n >= 30) {
break;
}
}
fclose(sorgente);
printf("\n\n\n");
}
while ( each < n) {
printf ( "n %d\n codice %s\n nome %s\n produttore %s\n categoria %s\n prezzo %f\n eta_min %d\n"
, each
, database[each].codice
, database[each].nome
, database[each].produttore
, database[each].categoria
, database[each].prezzo
, database[each].eta_min);
each++;
}
return 0;
}
char *extractstr ( char * source, char *target, int max) {
char *semicolon = NULL;
int span = 0;
semicolon = strpbrk ( source, ";");//find the next ;
if ( !semicolon) {
return source + 1;//handle the problem
}
span = ( semicolon - source);//get span of characters between ;
if ( span > max) {
span = max;//make sure not to exceed size of array
}
strncpy ( target, source, span);
target[span] = '\0';
return semicolon + 1;
}
char *extractfloat ( char * source, float *targetfloat) {
char *semicolon = NULL;
char *comma = NULL;
semicolon = strpbrk ( source, ";");//find the next ;
if ( !semicolon) {
return source + 1;//handle the problem
}
comma = strpbrk ( source, ",");//find comma
if ( comma && comma < semicolon) {
*comma = '.';//change comma to dot
}
*targetfloat = 0.0f;
sscanf ( source, "%f", targetfloat);
return semicolon + 1;
}
char *extractint ( char * source, int *targetint) {
char *semicolon = NULL;
semicolon = strpbrk ( source, ";\n");//find the next ; or \n
if ( !semicolon) {
return source + 1;//handle the problem
}
*targetint = 0;
sscanf ( source, "%d", targetint);
return semicolon + 1;
}