2017-02-19 40 views
-2

無法處理pipe函數,其中一個進程向其中一個進程發送字符串消息給第二個進程,第二個進程將消息中每個字符的大小寫反向並將其發送回第一個過程。無法處理管道功能

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <string.h> 
#include <ctype.h> 
#include <assert.h> 
    #include <stdbool.h> 

    // Parent: reads from P1_READ, writes on P1_WRITE 
    // Child: reads from P2_READ, writes on P2_WRITE 

#define P1_READ  0 
#define P2_WRITE 1 
#define P2_READ  2 
#define P1_WRITE 3 

// the total number of pipe *pairs* we need 
#define NUM_PIPES 2 
/* 
toggleString accepts an a pointer to char array, allocates size for the  
string to be toggled, 
    copys the argument into a string, loops through the string and for every 
uppercase character 
we set it to its lower case counterpart and vice versa, returning the 
    toggled string 
    */ 
    char *toggleString(char *argv){ 

int i;  /* Declare counter */ 

char *str = malloc(sizeof(argv[1])); /* Declare array sizeof input */ 

strcpy(str, argv); /* Copy String to char array */ 

for(i=0;str[i]!='\0';i++) { //Loop through length of string 

    if(str[i]>='A'&&str[i]<='Z'){ //if the array at i is uppercase 

    str[i]+=32;   //Make it lower case 

    } else if (str[i]>='a'&&str[i]<='z') {// if the array at i is lowercase 

    str[i]-=32;    //Make it uppercase 

    } 

} 

    return str; 

    } 

    /* 
    int inputValidation accept and integer (number of arugments) and a  
pointer to the cmd line input array 
    We check to see if the command line input contains the minimal number of  
arugments and check to see  
    whether or not the user input contains at least one reversible haracter,  
if all goes well we return 0 
*/ 
    int inputValidation(int argc, char *argv[]){ 

    int i;   //Declare counter variable 

    bool c = false; //Declare boolean flag using imported <stdbool.h> 

    char str[strlen(argv[1])]; //Declare str 

    strcpy(str, argv[1]); //copy argument into str 

    if (argc != 2) { // check to see if we have enough arguments to 
    continue  
         // Prompt user of correct usage 

    fprintf(stderr, "\nUsage: %s <string> or <'string 1, string 2', ...,     

    string n'> for multiple strings\n", argv[0]); 

    exit(EXIT_FAILURE); //Exit on improper input 

    } else { 
       //loop through our string 
    for(i=0;i<strlen(str);i++) { 
       //if any any char is a reversible character 
    if(isalpha((int) str[i])){ 

     c = true; //set the flag to true 

    } 

    } 

    if(c == false){ //If flag is false input does not contain any 

    reversible charachters 

      printf("\nSorry, The string you entered did NOT contain any  

     Alphabetical Characters\nRun me again, with at least 1 Alphabetical  

     character\n\n"); 

     exit(EXIT_FAILURE); //Exit on improper input 

    } 

    return (0); 

    }  

    } 

/* 主要需要輸入命令行,調用輸入驗證使
正確輸入的確認, 然後創建我們需要管道和叉子進程,父
和兒童 執行他們各自的代碼 */

int main(int argc, char *argv[]) { 

    assert(argc>1); 

    int fd[2*NUM_PIPES]; //Declare int[] of file descriptors 

    int len, i;    //Declare length and integer for count 

    pid_t pid;    //Declare process id 

    char parent[strlen(argv[1])]; //Declare Parent array 

char child[strlen(argv[1])]; //Declare Child array 

if(inputValidation(argc, argv) == 0) /* Check for proper input */ 

    strcpy(parent, argv[1]); 

// create all the descriptor pairs we need 
    for (i=0; i<NUM_PIPES; ++i) 
    { 
    if (pipe(fd+(i*2)) < 0) 
    { 
     perror("Failed to allocate pipes"); 
     exit(EXIT_FAILURE); 
    } 
    } 

// fork() returns 0 for child process, child-pid for parent process. 
    if ((pid = fork()) < 0) 
    { 
    perror("Failed to fork process"); 
    return EXIT_FAILURE; 
    } 
//////////////////////////////Childs Code  
BEGINS////////////////////////////////// 


// if the pid is zero, this is the child process 
    if (pid == 0) 
    { 
    // Child. Start by closing descriptors we 
    // don't need in this process 
    close(fd[P1_READ]); 
    close(fd[P1_WRITE]); 

    // used for output 
    pid = getpid(); 

    // wait for parent to send us a value 
    len = read(fd[P2_READ], &child, len); 
    if (len < 0) 
    { 
     perror("Child: Failed to read data from pipe"); 
     exit(EXIT_FAILURE); 
    } 
    else if (len == 0) 
    { 
     // not an error, but certainly unexpected 
     fprintf(stderr, "Child: Read EOF from pipe"); 
    } 
    else 
    { 

      // report pid to console 
     printf("Child(%d): Recieved Message\n\nChild(%d): Toggling Case and 
    Sending to Parent\n",pid, pid); 

     // send the message to toggleString and write it to pipe// 
     if (write(fd[P2_WRITE], toggleString(child), strlen(child)) < 0) 
     { 
      perror("Child: Failed to write response value"); 
      exit(EXIT_FAILURE); 

     } 

    } 

    // finished. close remaining descriptors. 
    close(fd[P2_READ]); 
    close(fd[P2_WRITE]); 

    return EXIT_SUCCESS; 
    } 
    //child code ends/// 
//////////////////////////////Parent Code  
BEGINS////////////////////////////////// 

    // Parent. close unneeded descriptors 
    close(fd[P2_READ]); 
    close(fd[P2_WRITE]); 

    // used for output 
    pid = getpid(); 

    // send a value to the child 

    printf("\nParent(%d): Sending %s to Child\n\n", pid, argv[1]); 
    if (write(fd[P1_WRITE], argv[1], strlen(argv[1])) != strlen(argv[1])) 
    { 
    perror("Parent: Failed to send value to child "); 
    exit(EXIT_FAILURE); 
    } 

    // now wait for a response 
    len = read(fd[P1_READ], &parent, strlen(parent)); 
    if (len < 0) 
    { 
    perror("Parent: failed to read value from pipe"); 
    exit(EXIT_FAILURE); 
    } 
    else if (len == 0) 
    { 
    // not an error, but certainly unexpected 
    fprintf(stderr, "Parent(%d): Read EOF from pipe", pid); 
    } 
    else 
    { 
    // report what we received 
    printf("\nParent(%d): Received %s from Child\n\n", pid, parent); 
    } 

    // close down remaining descriptors 
    close(fd[P1_READ]); 
    close(fd[P1_WRITE]); 

    // wait for child termination 
    wait(NULL); 

    return EXIT_SUCCESS; 

    } 
    //////////////////////////////Parent Code  
ENDS////////////////////////////////// 
+1

請選擇一種語言,C或C++ –

+0

這不是有效的C++代碼。 – melpomene

+2

如果您更整齊地格式化您的代碼,其他人閱讀起來要容易得多。我甚至不會查看沒有正確縮進的代碼。 – Galik

回答

1

這工作:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <string.h> 
#include <ctype.h> 
#include <assert.h> 
#include <stdbool.h> 

#define P1_READ  0 
#define P2_WRITE 1 
#define P2_READ  2 
#define P1_WRITE 3 

#define NUM_PIPES 2 

static 
char *toggleString(char *argv) 
{ 
    int i; 

    char *str = malloc(strlen(argv) + 1); /* Key Fix */ 

    strcpy(str, argv); 

    for (i = 0; str[i] != '\0'; i++) 
    { 
     if (str[i] >= 'A' && str[i] <= 'Z') 
     { 
      str[i] += 32; 
     } 
     else if (str[i] >= 'a' && str[i] <= 'z') 
     { 
      str[i] -= 32; 
     } 
    } 

    return str; 
} 

static 
int inputValidation(int argc, char *argv[]) 
{ 
    bool c = false; 

    char str[strlen(argv[1])]; 

    strcpy(str, argv[1]); 

    if (argc != 2) 
    { 
     fprintf(stderr, "\nUsage: %s <string> or <'string 1, string 2', ..., string n'> for multiple strings\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     for (size_t i = 0; i < strlen(str); i++) 
     { 
      if (isalpha((int)str[i])) 
      { 
       c = true; 
      } 
     } 

     if (c == false) 
     { 
      printf("\nSorry, The string you entered did NOT contain any" 
        " Alphabetical Characters\nRun me again, with at least 1 Alphabetical" 
        " character\n\n"); 
      exit(EXIT_FAILURE); 
     } 

     return(0); 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    assert(argc > 1); 

    int fd[2 * NUM_PIPES]; 
    int len, i; 
    pid_t pid; 
    char parent[strlen(argv[1])]; 
    char child[strlen(argv[1])]; 

    if (inputValidation(argc, argv) == 0) 
     strcpy(parent, argv[1]); 

    for (i = 0; i < NUM_PIPES; ++i) 
    { 
     if (pipe(fd + (i * 2)) < 0) 
     { 
      perror("Failed to allocate pipes"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    if ((pid = fork()) < 0) 
    { 
     perror("Failed to fork process"); 
     exit(EXIT_FAILURE); 
    } 

    if (pid == 0) 
    { 
     close(fd[P1_READ]); 
     close(fd[P1_WRITE]); 

     pid = getpid(); 

     len = read(fd[P2_READ], child, sizeof(child)); 
     if (len < 0) 
     { 
      perror("Child: Failed to read data from pipe"); 
      exit(EXIT_FAILURE); 
     } 
     else if (len == 0) 
     { 
      fprintf(stderr, "Child: Read EOF from pipe\n"); 
     } 
     else 
     { 
      child[len] = '\0'; 
      printf("Child(%d): Received Message [%s]\nChild(%d): Toggling Case and Sending to Parent\n", pid, child, pid); 
      char *toggled = toggleString(child); 
      printf("Child(%d): Sending [%s]\n", pid, toggled); 

      if (write(fd[P2_WRITE], toggled, len) < 0) 
      { 
       perror("Child: Failed to write response value"); 
       exit(EXIT_FAILURE); 
      } 
      free(toggled); 
     } 

     close(fd[P2_READ]); 
     close(fd[P2_WRITE]); 

     return EXIT_SUCCESS; 
    } 

    close(fd[P2_READ]); 
    close(fd[P2_WRITE]); 

    pid = getpid(); 

    printf("\nParent(%d): Sending [%s] to Child\n\n", pid, argv[1]); 
    len = strlen(argv[1]); 
    if (write(fd[P1_WRITE], argv[1], len) != len) 
    { 
     perror("Parent: Failed to send value to child"); 
     exit(EXIT_FAILURE); 
    } 

    len = read(fd[P1_READ], parent, sizeof(parent)); 
    if (len < 0) 
    { 
     perror("Parent: failed to read value from pipe"); 
     exit(EXIT_FAILURE); 
    } 
    else if (len == 0) 
    { 
     fprintf(stderr, "Parent(%d): Read EOF from pipe\n", pid); 
    } 
    else 
    { 
     parent[len] = '\0'; 
     printf("\nParent(%d): Received [%s] from Child\n\n", pid, parent); 
    } 

    close(fd[P1_READ]); 
    close(fd[P1_WRITE]); 

    wait(NULL); 

    return EXIT_SUCCESS; 
} 

從您的評論中提取代碼並拆分多行字符串等是很痛苦的。 toggleString()功能被破壞 - 分配1個字節,然後複製一個字符串。其他代碼對於空字符串和處理它們並不注意。這些基本上是評論中診斷出的問題。

採樣運行:

$ pp53 'AbSoLuTeLy GlOrIoUs' 

Parent(5209): Sending [AbSoLuTeLy GlOrIoUs] to Child 

Child(5210): Received Message [AbSoLuTeLy GlOrIoUs] 
Child(5210): Toggling Case and Sending to Parent 
Child(5210): Sending [aBsOlUtElY gLoRiOuS] 

Parent(5209): Received [aBsOlUtElY gLoRiOuS] from Child 

$