簡體   English   中英

C通過命名管道發送分配的字符串-Linux

[英]C sending allocated strings through named pipe - linux

我想通過命名管道而不是簡單的char數組發送分配的字符串。

我得到以下代碼:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>

int main()
{
    int pid, fd;
    fd = mkfifo("fifo.ftc", S_IRUSR | S_IWUSR);
    pid = fork();

    char* send, * recieve;

    if(pid == 0) {
        recieve = malloc(100);
        fd = open("fifo.ftc", O_RDONLY);
        read(fd, recieve, sizeof(recieve));
        close(fd);
        printf("%s\n", recieve);

        send = malloc(100);
        send = "This text was sent by child!";
        fd = open("fifo.ftc", O_WRONLY);
        write(fd, send, sizeof(send));
        close(fd);

        free(recieve);
        free(send);

    } else if(pid > 0) {
        send = malloc(100);
        send = "This text was sent by parent!";
        fd = open("fifo.ftc", O_WRONLY);
        write(fd, send, sizeof(send));
        close(fd);

        recieve = malloc(100);
        fd = open("fifo.ftc", O_RDONLY);
        read(fd, recieve, sizeof(recieve));
        close(fd);
        printf("%s\n", recieve);

        unlink("fifo.ftc");

        free(send);
        free(recieve);
    }
}

作為輸出,我始終會收到:

This tex
This tex

看起來好像並沒有打印出整個字符串。 如何接收父母和孩子的全部信息?

您的代碼中存在多個錯誤。

  1. 您必須記住, 讀取寫入均不能保證它們會有效地讀取或寫入您告訴他們的字節數。

    從Linux編寫手冊頁:

    概要

    #include <unistd.h>

    ssize_t write(int fd,const void * buf,size_t count);

    描述

    write()從緩沖區buf指向文件描述符fd所引用的文件最多寫入計數字節。 例如, 如果底層物理介質上的空間不足,或者遇到RLIMIT_FSIZE資源限制(請參閱setrlimit(2)),或者在調用之后被信號處理程序中斷,則寫入的字節數可能少於count。寫少於計數字節。 (另請參見pipe(7)。)

    它們返回已讀取或寫入的字節數,因此您必須將其返回值存儲在變量中並進行相應的處理。 通常,將它們包裝在一個循環中,保留一個計數器以累積讀取/寫入的字節數,並在達到原始緩沖區大小或返回錯誤值時退出循環。

  2. 正如@wildplasser在評論中提到的那樣,您正在濫用sizeof運算符。 當你做char *foo; sizeof foo; char *foo; sizeof foo; ,生成的大小不是foo指向的字符串的大小,而是char指針類型的大小(64位體系結構中為8個字節,32位中為4個字節)。 您應該改用strlen(foo)

@jweyrich已經回答了您問題的要點。 但是,您可能還需要考慮其他幾點...

在使用該語言入門時,C語言中的字符串分配有時是一個混亂點,因為有時會出現以下情況:

send = "This text was sent by parent!";

將工作,而其他人則行不通。 在這種情況下它可以工作,因為在代碼中send的變量是作為指針創建的。 請記住,如果已將其創建為數組,則初始化期間只能使用=運算符進行賦值。 對C字符串的char array形式的初始化后賦值必須進行不同的處理。 通常,字符串函數( strcpystrcatsprintf等)用於修改字符串或對字符串進行賦值。 例子:

//string literal used to initialize
char send[100] = "This text was sent by parent!"; //works

//initialized with nul terminator
char send[100] = '\0';
//post initialization statements:
strcpy(send, "This text was sent by parent!");//works
strcat(send, "This text was sent by parent!");//works
sprintf(send, "%s", "This text was sent by parent!");//works

但:

send = "This text was sent by parent!"; //does not work;

更多關於弦的信息

另外,建議您始終檢查malloc()的返回值,以確保確實分配了內存:

send = malloc(100);
if(!send) return -1; //check return of malloc
send = "This text was sent by parent!";

還有一點:因為recieve是指針,所以它的大小將是包含其地址所需的字節數,對於32位目標,可能是4個字節,對於64位目標,可能是8個字節。 所以聲明:

read(fd, recieve, sizeof(recieve));

很可能告訴read讀取4或8個字節,這與您預期的不太可能。 將此行更改為:

read(fd, recieve, 100);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM