如果条件和函数返回分段错误错误,则无法输入

时间:2015-01-16 10:19:42

标签: c if-statement segmentation-fault

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

  1. 当用户输入compilar -l时,它应该输入if(i==1 && strcmp(c,"l")==0)但不输入...如果用户输入compilar -c 0,则输入第二个if假设{1}}条件。我不知道为什么第一个如果不起作用......

  2. 如果我输入listartarefas()(前一段时间,第一个if工作,我可以测试一下)它会给我一个分段错误错误。

  3. 有人可以帮帮我吗?

    Listartarefas()函数:

    #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;
    }
    

1 个答案:

答案 0 :(得分:0)

  1. Iffy条件

    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);
      }
    

    第一次调用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);
      }
    
  2. 功能错误

    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)时,它(有一些例外)转换为指向其第一个元素的指针。这意味着您将Task *传递给listartarefas(),但该函数需要Task **。这显然无法奏效。

    如果您使用一组健康的警告编译代码,编译器会通知您这些问题。根据您提供的信息,我建议您更改listartarefas()功能,如下所示:

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

    read(fd1,&buffer,sizeof(buffer)); //Lê o que se encontra no buffer
    

    您永远不会测试read()的返回值。


    while(1)
    {
      ...
    }
    

    您似乎没有办法退出此循环。


    strcpy(c,t);
    

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