Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我应该如何将文件中的令牌解析为结构?_C_File_Csv_Parsing_Struct - Fatal编程技术网

C 我应该如何将文件中的令牌解析为结构?

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

我需要将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;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;
}