2015-11-26 2 views
-1

Я пытаюсь написать программу оболочки в C для перенаправления ввода-вывода. Ввод и вывод работают нормально, но я также должен добавить вывод в конец файла с помощью «>>», но он не работает. Всякий раз, когда я использую >> в командной строке, он просто перезаписывает вывод в файл. И я также получаю предупреждение при запуске программы: предупреждение: многосимвольная символьная константа. Я был бы очень признателен, если кто-то может помочь мне в правильном направлении, чтобы исправить эту проблему.Как добавить в конец файла для оболочки в C?

 // Check for redirected input 
     input = redirect_input(args, &input_filename); 

     switch(input) { 
     case -1: 
      printf("Syntax error!\n"); 
      continue; 
      break; 
     case 0: 
      break; 
     case 1: 
      printf("Redirecting input from: %s\n", input_filename); 
      break; 
     } 

     // Check for redirected output 
     output = redirect_output(args, &output_filename); 

     switch(output) { 
     case -1: 
      printf("Syntax error!\n"); 
      continue; 
      break; 
     case 0: 
      break; 
     case 1: 
      printf("Redirecting output to: %s\n", output_filename); 
      break; 
     } 

     // Check for redirected append output 
     append = redirect_append(args, &append_filename); 

     switch(append) { 
     case -1: 
      printf("Syntax error!\n"); 
      continue; 
      break; 
     case 0: 
      break; 
     case 1: 
      printf("Redirecting output to: %s\n", output_filename); 
      break; 
     } 



     // Do the command 
     do_command(args, block, 
       input, input_filename, 
       output, output_filename, 
       append, append_filename); 
     } 
    } 


    /* 
    * Do the command 
    */ 
    int do_command(char **args, int block, 
       int input, char *input_filename, 
       int output, char *output_filename, 
       int append, char *append_filename) { 

     int result; 
     pid_t child_id; 
     int status; 

     // Fork the child process 
     child_id = fork(); 

     // Check for errors in fork() 
     switch(child_id) { 
     case EAGAIN: 
     perror("Error EAGAIN: "); 
     return; 
     case ENOMEM: 
     perror("Error ENOMEM: "); 
     return; 
     } 

     if(child_id == 0) { 

     // Set up redirection in the child process 
     if(input) 
      freopen(input_filename, "r", stdin); 

     if(output) 
      freopen(output_filename, "w+", stdout); 

     if (append) 
      freopen(append_filename, "a", stdout); 

     // Execute the command 
     result = execvp(args[0], args); 

     exit(-1); 
     } 

     // Wait for the child process to complete, if necessary 
     if(block) { 
     printf("Waiting for child, pid = %d\n", child_id); 
     result = waitpid(child_id, &status, 0); 
     } 
    } 

    /* 
    * Check for input redirection 
    */ 
    int redirect_input(char **args, char **input_filename) { 
     int i; 
     int j; 

     for(i = 0; args[i] != NULL; i++) { 

     // Look for the < 
     if(args[i][0] == '<') { 
      //free(args[i]); 

      // Read the filename 
      if(args[i+1] != NULL) { 
     *input_filename = args[i+1]; 
      } else { 
     return -1; 
      } 

      // Adjust the rest of the arguments in the array 
      for(j = i; args[j-1] != NULL; j++) { 
     args[j] = args[j+2]; 
      } 

      return 1; 
     } 
     } 

     return 0; 
    } 

    /* 
    * Check for output redirection 
    */ 
    int redirect_output(char **args, char **output_filename) { 
     int i; 
     int j; 

     for(i = 0; args[i] != NULL; i++) { 

     // Look for the > 
     if(args[i][0] == '>') { 
      //free(args[i]); 

      // Get the filename 
      if(args[i+1] != NULL) { 
     *output_filename = args[i+1]; 
      } else { 
     return -1; 
      } 

      // Adjust the rest of the arguments in the array 
      for(j = i; args[j-1] != NULL; j++) { 
     args[j] = args[j+2]; 
      } 

      return 1; 
     } 
     } 

     return 0; 
    } 

    /* 
    * Check for append redirection 
    */ 
    int redirect_append(char **args, char **append_filename) { 
     int i; 
     int j; 

     for(i = 0; args[i] != NULL; i++) { 

     // Look for the >> 
     if(args[i][0] == '>' && args[i][1] == '>') { 
      //free(args[i]); 

      // Read the filename 
      if(args[i+2] != NULL) { 
     *append_filename = args[i+2]; 
      } else { 
     return -1; 
      } 

      // Adjust the rest of the arguments in the array 
      for(j = i; args[j-1] != NULL; j++) { 
     args[j] = args[j+2]; 
      } 

      return 1; 
     } 
     } 

     return 0; 
    } 
+0

Фиксация предупреждения должна быть легкой, по крайней мере, вы знаете, где она находится. Может быть, вы можете нам рассказать? –

+0

TL; DR. Предоставьте [mcve]. – Olaf

ответ

0
if(args[i][0] == '>>') { 

Должно быть:

if(args[i][0] == '>' && args[i][1] == '>') { 

Это источник вашей "мульти-символьной константы" предупреждение, а также ваши проблемы перенаправления вывода.

+0

Удалено предупреждение, но >> все еще перезаписывает все, что было в выходном файле. – Truecolor

+0

Ваша логика «>» противоречит вашей логике «>>». Вы должны, вероятно, справиться с этим вместе. – keithmo

+0

Я смущен тем, как достичь этой логики. – Truecolor

Смежные вопросы