Can';t在if条件下输入,函数返回分段故障错误

Can';t在if条件下输入,函数返回分段故障错误,c,if-statement,segmentation-fault,C,If Statement,Segmentation Fault,这个程序应该通过管道在客户端和服务器之间进行通信。沟通已经开始,但我仍然有两个问题: 当用户键入compiler-l时,如果(i==1&&strcmp(c,“l”)==0)但它不。。。如果用户键入compiler-c0,它将在假定的第二个If条件下输入。我不知道为什么第一个if不起作用 如果我在listarefas()(前一段时间,第一个If有效,因此我可以测试它),它会给我一个分段错误 谁能帮帮我吗 listarefas()函数: #define TAM_MAX 99 int num = 0

这个程序应该通过管道在客户端和服务器之间进行通信。沟通已经开始,但我仍然有两个问题:

  • 当用户键入
    compiler-l
    时,如果(i==1&&strcmp(c,“l”)==0)但它不。。。如果用户键入
    compiler-c0
    ,它将在假定的第二个
    If
    条件下输入。我不知道为什么第一个if不起作用

  • 如果我在
    listarefas()
    (前一段时间,第一个
    If
    有效,因此我可以测试它),它会给我一个分段错误

  • 谁能帮帮我吗

    listarefas()函数:

    #define TAM_MAX 99
    
    int num = 0;
    
    void listartarefas(Task **tf)
    {
      int i;
      for(i=0;i<=(TAM_MAX-1);i++)
      {
        if(tf[i]->tipo == 1)
        {
          printf("Agendada:\n");
          printf("%d\n",tf[i]->identf);
          printf("%s\n",(tf[i]->path));
          printf("%d-%d-%d\n",(tf[i]->ano),(tf[i]->mes),(tf[i]->dia));
          printf("%d:%d:%d\n",(tf[i]->hora),(tf[i]->min),(tf[i]->seg));
        }
        else
        {
          printf("Executada:\n");
          printf("%d\n",tf[i]->identf);
          printf("%s\n",(tf[i]->path));
          printf("%d-%d-%d\n",(tf[i]->ano),(tf[i]->mes),(tf[i]->dia));
          printf("%d:%d:%d\n",(tf[i]->hora),(tf[i]->min),(tf[i]->seg));
        }
      }
    }
    
    int main()
    {
      int fd1, fd2;
      int n=0;
      int v =1;
      int i=0;
      char *t;
      char c[2]="";
      Task recebido;
      char buffer[70]=""; //Buffer que guarda o que o cliente envia
      char buffer2[1]=""; //Buffer que guarda o que o servidor envia
    
      Task tf[TAM_MAX]; //Array de tarefas: onde estão guardadas todas as tarefas introduzidas pelo cliente
    
      if (access("fifo", F_OK) == -1) //Testa se o ficheiro existe
      {
        if (mkfifo("fifo", 0666) == -1) { //Criar fifo para ler o buffer recebido pelo cliente
          perror("fifo ler");
          return EXIT_FAILURE;
        }
      }
    
      if (access("fifo2", F_OK) == -1)
      {
        if (mkfifo("fifo2", 0666) == -1) //Criar fifo para escrever no buffer2 e enviar para o cliente
        {
          perror("fifo escrever");
          return EXIT_FAILURE;
        }
      }
    
      if ((fd1 = open("fifo", O_RDONLY)) == -1) { //abrir fifo para ler
        perror("fifo ler");
        return EXIT_FAILURE;
      }
    
      if ((fd2 = open("fifo2", O_WRONLY)) == -1) { //abrir fifo2 para escrita
        perror("fifo escrever");
        return EXIT_FAILURE;
      }
    
      while(1)
      {
        read(fd1,&buffer,sizeof(buffer)); //Lê o que se encontra no buffer
        t = strtok(buffer," -:");  //Vai quebrando o que está no buffer à medida que faz o ciclo infinito
    
        while( t != NULL)
        {
          if(i==1)
          {
            strcpy(c,t); //Vai copiando o que foi quebrado para c
          }
          if(i==1 && strcmp(c,"l")==0)
          {
            printf("Listar tarefas");
            listartarefas(tf);
          }
          if(i==2 && strcmp(c,"c")==0)
          {
            n=atoi(t);
            v=0;
            cancelartarefa(tf,&num, n);
          }
          t = strtok(NULL, " -:"); 
          i++;
        }
        v=1;
        i=0;
    
        memset(buffer,0, sizeof(buffer));
    
        sleep(2);
      }
      close(fd1);
      close(fd2);
      remove("fifo");
      remove ("fifo2");
    
      return EXIT_SUCCESS;
    }
    
  • 不确定的条件

    t = strtok(buffer," -:");
    
    while( t != NULL)
    {
      if(i==1)
      {
        strcpy(c,t); //Vai copiando o que foi quebrado para c
      }
      if(i==1 && strcmp(c,"l")==0)
      {
        printf("Listar tarefas");
        listartarefas(tf);
      }
      if(i==2 && strcmp(c,"c")==0)
      {
        n=atoi(t);
        v=0;
        cancelartarefa(tf,&num, n);
      }
    
    read(fd1,&buffer,sizeof(buffer)); //Lê o que se encontra no buffer
    
    strtok()
    的第一次调用返回第一个令牌(命令)。此时,
    i==0
    ,因此不会执行任何分支。类似地,当解析第二个令牌(参数)时,
    i==1
    ,因此也不会执行第三个分支。您需要基于零的索引:

    t = strtok(buffer," -:");
    
    while( t != NULL)
    {
      if(i==0)
      {
        strcpy(c,t); //Vai copiando o que foi quebrado para c
      }
      if(i==0 && strcmp(c,"l")==0)
      {
        printf("Listar tarefas");
        listartarefas(tf);
      }
      if(i==1 && strcmp(c,"c")==0)
      {
        n=atoi(t);
        v=0;
        cancelartarefa(tf,&num, n);
      }
    
  • 功能故障

    void listartarefas(Task **tf)
    {
      ...
      if(tf[i]->tipo == 1)
      { 
        printf("Agendada:\n");
        printf("%d\n",tf[i]->identf);
        printf("%s\n",(tf[i]->path));
      ...
    }
    
    Task tf[TAM_MAX];
    ...
    listartarefas(tf);
    
    在表达式中使用数组(
    tf
    )时,它(除某些例外)会转换为指向其第一个元素的指针。这意味着您正在将一个
    任务*
    传递给
    listarefas()
    ,但函数需要一个
    任务**
    。这显然是行不通的

    如果您在编译代码时启用了一组正常的警告,编译器将通知您这些问题。根据您提供的信息,我建议您将
    listarefas()
    函数更改如下:

    void listartarefas(Task *tf)
    {
      ...
      if(tf[i].tipo == 1)
      { 
        printf("Agendada:\n");
        printf("%d\n",tf[i].identf);
        printf("%s\n",(tf[i].path));
      ...
    }
    
  • 其他观察结果

    t = strtok(buffer," -:");
    
    while( t != NULL)
    {
      if(i==1)
      {
        strcpy(c,t); //Vai copiando o que foi quebrado para c
      }
      if(i==1 && strcmp(c,"l")==0)
      {
        printf("Listar tarefas");
        listartarefas(tf);
      }
      if(i==2 && strcmp(c,"c")==0)
      {
        n=atoi(t);
        v=0;
        cancelartarefa(tf,&num, n);
      }
    
    read(fd1,&buffer,sizeof(buffer)); //Lê o que se encontra no buffer
    
    您从不测试
    read()
    的返回值


    你似乎没有办法退出这个循环


    c
    中只有一个字符和一个终止零的空间,但您从不检查令牌
    t
    的长度。这很容易导致缓冲区溢出


  • 你只是在传递任务*。您真的应该认真对待编译器警告。@leppie但是我该如何解决这个问题呢?如果我将函数的参数更改为“Task*tf”,它将无法正确打印,因为当您使用
    Task*tf
    时,还有另一个警告,您也可以忽略。我知道有一个警告,我只是试图解决它……segdault来自
    任务**tf
    。如果正确使用了
    Task*tf
    Task tf[]
    ,则不应出现错误。现在,我可以看到您的
    任务tf[TAM_MAX]
    从未初始化,这可能不是您想要的。