繁体   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