2012-06-08 46 views
0

我用一個簡單的fork()來模擬客戶端/服務器,然後一個非常簡單的管道來發送/接收最大長度爲30的字符緩衝區,但它最終打印不可打印的字符(小「?」和一個有4個1和0的框)AFTER所需的單詞。簡單的30字符緩衝區管道打印不可打印的字符,不知道爲什麼

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

int main() { 
    int pipefd[2]; 
    int cpid; 
    char buf[31]; 
    if (pipe(pipefd) == -1) { 
     perror("pipe"); 
     exit(EXIT_FAILURE) 
    } 
    cpid = fork(); 
    if (cpid == -1) P 
     perror("cpid"); 
     exit(EXIT_FAILURE); 
    } 
    if (cpid == 0) {  // child reads from pipe 
     close (pipefd[1]); // close unused write end 
     read (pipefd[0], &buf, 30); // if I use 30 instead of strlen(buf) it prints Server transmit: Server receives. It does not wait for write. Makes no sense 
     printf ("Server receives: %s", buf); 
     close (pipefd[0])l 
     exit (EXIT_SUCCESS); 
    } 
    else {    // parent writes to pipe 
     close (pipefd[0]); // closing unused read end; 
     char buf2[30]; 
     printf("Server transmits: "); 
     scanf ("%s", buf2); 
     write (pipefd[1], buf2, strlen(buf2)); 
     close(pipefd[1]); 
     wait(NULL); 
     exit(EXIT_SUCCESS); 
    } 
    return 0; 
} 

此外,如果我寫了不止一個單詞,它會忘記第二個。在C++中,我使用getline(cin,string),但這不是一個選項。

也使用read (pipefd[0], &buf, sizeof(buf));,現在它按正確的順序打印(不知道爲什麼strlen不起作用),但我仍然在最後得到不可打印的字符。

回答

3

當你write (pipefd[1], buf2, strlen(buf2));你忽略把在流中。將其更改爲:

write (pipefd[1], buf2, strlen(buf2)+1); 

而且您的字符串現在將包含空終止符,從而防止垃圾到最後。

使用read (pipefd[0], &buf, strlen(buf))不起作用,因爲buf未初始化。 strlen是一個簡單的函數,它在字符串的末尾查找終止的null,並在找到時停止。與C++向量的功能不同,C函數無法訪問內存元數據。 (sizeof是一個運營商)

+0

現在我覺得很糟糕,因爲我已經知道,只是...錯過了它。但現在。我如何閱讀多於一個字? – Kalec

+0

將'read'和'write'放入循環中。 – Dave

+0

這不會造成溢出的機會嗎?或者我該如何指定何時結束循環?你能給我一個簡單的例子嗎?我知道我可以'while(讀(pipefd [0],&buf,1)> 0)'然後做一個計數器。讓我試試 – Kalec

相關問題