簡體   English   中英

使用 fgets 和 strtok 從文件中讀取數據時出現分段錯誤

[英]segmentation fault when reading data from a file with fgets and strtok

我從 c 開始,我們被要求用 C 語言創建一個小型 TCP/IP 應用程序。 一開始我做得很好,我已經測試了服務器和客戶端並且它們正在通信但是當我開始開發應用程序的主要主題時:客戶端連接到服務器並通過它的參考請求一本書. 服務器它自己讀取一個文件,其中包含一些書的行,如下所示(參考;作者姓名;標題;性別),正如您在代碼中看到的那樣,我想讀取文件並將每一行存儲在二維中桌子。

然后服務器比較客戶端發送的參考文獻並將其與我在表中的內容進行比較,如果它存在,他會將那本書的信息發送給客戶端。(抱歉,詞組太多但我正在嘗試盡可能說清楚)。 因此,當我編譯服務器並嘗試執行它時,出現了分段錯誤...:(。這是代碼。如果您能提供幫助,那將是完美的..

 #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <errno.h>
    
    
    #define MAX_LIGNE 256
    
    /*typedef struct{
        int numRef;
        char nomAuteur[50];
        char titre[50];
        char genre[20];
    } biblio ;*/
    
    void handler(int sig){
        wait(NULL);
    }
    
    int main (int argc, char **argv){
        struct sigaction ac;
    
        ac.sa_handler = &handler;
        ac.sa_flags = SA_RESTART;
        char ligne[61];
        char *elem=(char *)malloc(sizeof(char)*100);
        int i=0;
        //biblio tab[30];
        char *tab[50][4]={0};
        //Stockage des données du fichier dans un tableau
        //ouverture du fichier en lecture seule
        //char *fichier=";
        FILE * fd;
        fd=fopen("./fichier-exemple.txt","r");
        if(fd==NULL){
            printf("Erreur lors de l'ouverture du fichier...\n");
        }
    
        //on stock les données du fichier dans la table de structure
    
        while(fgets(ligne,sizeof(ligne),fd)!=NULL){
    
            
        elem=strtok(ligne,";");
        tab[i][0]=(char *)malloc(strlen(elem)*sizeof(char));
        strcpy(tab[i][0],elem);
        
        elem=strtok(NULL,";");                  
        tab[i][1]=(char *)malloc(strlen(elem)*sizeof(char));
        strcpy(tab[i][1],elem); 
        
        elem=strtok(NULL,";");
        tab[i][2]=(char *)malloc(strlen(elem)*sizeof(char));
        strcpy(tab[i][2],elem); 
        
        elem=strtok(NULL,"\n");
        tab[i][3]=(char *)malloc(strlen(elem)*sizeof(char));
        strcpy(tab[i][3],elem); 
        i++;
        }
                            
        free(elem);
        fclose(fd);
        int longeur=i;
        //vérification du nombre d'arguments
        if(argc!=2){
            fprintf(stderr,"respectez la synthaxe: serveur <port> !\n");
            exit(0);
        } else {
    
        
        int port=atoi(argv[1]);
        //les structures s et c pour server et client respectivement
        struct sockaddr_in s,c;
    
        //création de socket
    
        int p=socket(AF_INET,SOCK_STREAM,0);
    
        if(p<0){
            printf("Erreur lors de la création du socket....\n");
            exit(0);
        }else{
            printf("Socket créé avec succès....\n");
            }
        //remplissage de la structure s
        s.sin_family=AF_INET;
        s.sin_addr.s_addr=htonl(INADDR_ANY);
        s.sin_port=htons(port);
    
        socklen_t Slen= (socklen_t)sizeof(c);
    
        //création de bind
    
        int b= bind(p,(const struct sockaddr *)&s, Slen);
        if(b<0){
            printf("Erreur lors du bind...\n");
            exit(0);
        }else{
            printf("Bind créé avec succès...\n");
        }
    
        //l'écoute
    
        int l= listen(p,20);
    
        if(l==-1){
            printf("Erreur d'écoute ...\n");
            exit(0);
        }else{
            printf("En écoute...\n");
            
        }
        //boucle infini pour accepter les demandes des clients
        while(1){
            int acpt=accept(p,(struct sockaddr *) &c, &Slen);
            if(acpt==-1){
                printf("Erreur d'acceptation...\n");
            }else{
                printf("Acceptation...\n");
            }
            int f=fork();
            if(f==0){
                char * res=(char *)calloc(MAX_LIGNE,sizeof(char));
                char  * buffer=(char *)calloc(MAX_LIGNE,sizeof(char));
                while(1){
                    
                    //réception du trajet depuis le client
                    //recv(acpt,buffer,MAX_LIGNE,0);
                    recv(acpt, &buffer, strlen(buffer),0);
                    int buf=atoi(buffer);
                    
                    //char ligne[50];
    
                    int j=0;
                    for(j=0;j<longeur;j++){
                    //printf("%s",tab[j].genre);
                        if(atoi(tab[j][0])==buf){
                            strcpy(res,tab[j][1]);
                            strcat(res, ", ");
                            strcat(res,tab[j][2]);
                            strcat(res, ", ");
                            strcat(res,tab[j][3]);
                            strcat(res,"\n");
                        }
                    }
    
                        
    
    
                    send(acpt,&res,strlen(res),0);
                }
                free(buffer);
                free(res);
            }else{
                sigaction(SIGCHLD,&ac,NULL);
            }
        }
        }
    }
            char * res=(char *)calloc(MAX_LIGNE,sizeof(char));
            ...
            send(acpt,&res,strlen(res),0);

您通過&res send 但是res是指向您要發送的數據的指針。 您實際上並不想將res發送到另一端——它是一個指針,其值僅對該進程有意義。

&res更改為res 您需要send一個指向您要發送的數據的指針,而不是指向您要發送的數據存儲地址的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM