2013-02-13 5 views
3

Я начал сегодня работать с трубой() и вилка() и Exec() в C, и теперь у меня есть проблема:Чтение/запись через трубу в C

Основная программа создает две трубы и вилки , Детский процесс выполняет exec() в другой программе, которая теперь является только тестовой программой, которая считывает из stdin, общается со своим родителем и записывает данные stdout ther. Основная программа должна получать данные, общаться с базой данных SQLite 3 и возвращать данные с использованием труб. Эта часть проблемы решена, трубы открыты и закрыты должным образом, и есть связь.

Тогда проблема в детском процессе (тот, который вызывается с Exec()) в какой-то момент у меня есть это:

printf("Strid sent: %s\n", strid); 
write(4,strid,sizeof(strid)); 

printf("Str sent: %s\n", str); 
write(4,str,sizeof(str)); 

И родитель должен читать правильно с этой частью :

read(select[0],strid, sizeof(strid)); 
printf("Strid recived: %s\n",strid); 
int id = atoi(strid); 
printf("Id recived: %d\n",id); 

read(select[0],buffer, sizeof(buffer)); 
printf("Buffer recived: %s\n",buffer); 

Но я Получать ти те Printf является:

Strid sent: 1 
Str sent: start 
Strid recived: 1 
Id recived: 1 
Buffer recived: 7� (and other strange characters) 

Как вы можете видеть, Prob lem находится в получении второй команды (и эта часть копируется как есть, в ней нет другого кода).

я должен сказать также, что «буфер» переменную, которая recives ул, объявлен как символ буфера [20] и не был использован до чтения()

Спасибо заранее!

+0

Что такое объявления для strid и str? –

+1

Если ребенок записывает байты sizeof (buffer) или более, родитель будет писать до тех пор, пока не достигнет 0 байт. Запись может также писать больше, чем длина интересных данных в str, вы должны, вероятно, написать strlen (str) байты вместо sizeof (str). И не забывайте о завершении 0. –

+0

Возможно, вы захотите использовать strlen вместо sizeof в функции записи.Просто любопытство, почему вы используете 4 в качестве файлового дескриптора вместо использования переменной? – REALFREE

ответ

3

После чтения, вам нужно добавить завершение 0 байт в конце, перед печатью, что-то вроде

int len = read(select[0], buffer, sizeof(buffer) - 1); 
if (len < 0) { 
    perror("read error"); 
} else { 
    buffer[len] = 0; 
    printf("Buffer recived: %s\n", buffer); 
} 

Так, Тон задает вещи, прочитать man page of read, или на самом деле человек страницы какой-либо функции, прежде чем использовать его ...

в качестве альтернативы, использовать некоторые stdio.h функцию, которая добавляет строку завершения 0 себя, вероятно, fgets если чтение построчно нормально.

+0

Как уже отмечал Кьелл Андреассен, и как вы уже упоминаете , размеры не соответствовали, и я был с ним несколько часов. спасибо – markmb

0

Трубы не отслеживают «границы» между режимами записи. Поэтому, если у вас есть несколько записей на трубе, все данные из этих записей могут возвращаться в ответ на одно чтение. Поэтому, если вы отправляете строку (например), за которой следует целое число, и вы пытаетесь прочитать строку в буфере, она получит в буфер как строку, так и следующее целочисленное целое число, похожее на мусор в конце строки , и размер, возвращаемый чтением, будет больше.

Кроме того, если труба заполняется, запись может не записывать все данные, которые вы ей запросили, - она ​​может писать только столько, сколько может поместиться на данный момент, и вам придется писать остальные позже ,

так ВСЕГДА проверяйте возвращаемые значения ваших звонков и будьте готовы к тому, чтобы получить меньше (или больше для read), чем вы ожидаете.

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