2013-08-14 2 views
2

Я написал простую программу, чтобы узнать, как писать сообщения на трубе в C, и при этом я нашел что-то довольно странное, что я не могу объяснить или понять, это код:Сообщение о трубе в c усекается

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MAXSIZE 100 
int fd[2]; 

void writeMsg() { 
    int i; 
    char message[MAXSIZE]; 
    for (i = 0; i < 12; i++) { 
     sprintf(message,"%d%d%d%d%d%d%d%d%d%d\n",i,i,i,i,i,i,i,i,i,i); 
     write(fd[1], message, strlen(message)); 
    } 
} 

int main() { 
    pipe(fd); 
    char message[MAXSIZE]; 
    int pid; 
    pid = fork(); 
    if (pid == 0) { 
     writeMsg(); 
    } 
    if (pid > 10) { 
     wait(NULL); 
     read(fd[0], message, MAXSIZE); 
     printf("%s", message); 
    } 
    return 0; 
} 

в writeMsg есть цикл, чтобы написать сообщение больше, чем MAXSIZE в трубе, после чего сообщение читается и печатается в основном, странное дело, если я использую strlen(message) в write(fd[1], message, strlen(message)) следующее сообщение напечатано:

0000000000 
1111111111 
2222222222 
3333333333 
4444444444 
5555555555 
6666666666 
7777777777 
8888888888 
9 

Но если вместо этого я использую write(fd[1], message, strlen(message)+1) сообщение является:

0000000000 

В чем разница между strlen(message) и strlen(message)+1? Здесь http://codewiki.wikidot.com/c:system-calls:write говорится, что если количество байтов для записи меньше, чем предоставленный буфер, выход усекается, но с +1 размер строки равен 11, что не больше MAXSIZE. Любые разъяснения или исправления приветствуются.

+0

Возможно, вы захотите вызвать 'read' в цикле и проверить возвращаемое значение, пока ничего больше не сможете прочитать. И/или установите MAXSIZE немного больше ... –

+0

Цель вопроса заключалась в том, чтобы понять, в чем разница, которую делает +1 в strlen. Если чтение вызывается в цикле, число итераций (или написанных сообщений) должно было быть заранее известно, не так ли? – user1493813

+0

Почему вы отказываетесь выполнять операцию чтения, если PID родителя меньше десяти? Я понимаю, что 'pid == 0' будет дочерним элементом fork, и вы никогда не получите' pid == 1', потому что это процесс init, но что особенного в pids '2',' 3', '4',' 5', '6',' 7', '8' и' 9'? –

ответ

2

+1 будет вызывать нуль в конце строки (после новой строки), что означает, что при печати буфера на другом конце printf останавливается после первой строки. Вы действительно не хотите посылать этот ноль, я так думаю, поэтому не делайте этого ...

Если вам действительно нужен нуль в конце строки через трубу, вам нужно будет выяснить где заканчивается каждая строка, и печатать их по отдельности, например используя strlen(), чтобы выяснить, сколько времени прошло сообщение, и используйте индекс, который перемещает index += strlen(&message[index])+1, и printf("%s", &message[index]); в цикле, пока вы не распечатали все (сравнительный индекс, насколько вы читали!).

Использование цикла до read возвращает нулевые байты, чтобы вы могли прочитать все входные данные (вы читаете слишком короткий прямо сейчас, вот почему вы не получаете все 9).

+0

Хм, не понял, спасибо за ответ и предложение Матс Петерсон. – user1493813

2

Происходит то, что при звонке write с strlen(message) + 1 также написано персонажем \0.

Это означает, что, когда read() ing, \0 будет добавлен в массив вашего символа. Поскольку printf() останавливается, когда находит \0, это является причиной того, что единственный напечатанный текст в том, что было написано вашим первым звонком до write().

+0

Вижу, спасибо за ясный ответ Xaqq. – user1493813

+0

@ user1493813 Добро пожаловать :) – Xaqq

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