2017-01-31 10 views
0

Я хочу искать символ в потоке и отсылать обратно в поток, не потребляя никаких данных. Я использую fgetc, но программа застревает в callling fgetc.Как искать символ в потоке и отбрасывать поток в потоке с помощью труб

ниже - моя тестовая программа.

int main(void) 
{ 
    int  fd[2], nbytes; 
    pid_t childpid; 
    char string[] = "Hello, world!\n"; 
    char readbuffer[80]; 

    pipe(fd); 

    if((childpid = fork()) == -1) 
    { 
     perror("fork"); 
     exit(1); 
    } 

    if(childpid == 0) 
    { 
     /* Child process closes up input side of pipe */ 
     close(fd[0]); 

     /* Send "string" through the output side of pipe */ 
     write(fd[1], string, (strlen(string)+1)); 
     exit(0); 
    } 
    else 
    { 
     /* Parent process closes up output side of pipe */ 
     close(fd[1]); 
     int dummy; 
     fd_set set; 
     struct timeval timeout; 
     FD_ZERO (&set); 
     FD_SET (fd[0], &set); 
     timeout.tv_sec = 1; 
     timeout.tv_usec = 0; 
     if (select (fd[0]+1, &set, NULL, NULL, &timeout)) 
     { 
      dummy = fgetc (stdin); 
      ungetc (dummy, stdin); 
      // Search for character 
      if (dummy == 0x03) 
       // Todo 
     } 
    } 

    return(0); 
} 

Итак, что не так с кодом, почему программа застряла на fgetc.

ответ

0

Вы пытаетесь использовать fgetc от stdin (это ваш терминал), а не труба. Вы нигде не используете трубку. Попытайтесь понять, что ваш код действительно делает.

Я думаю, вы намеревались dup2 труба fd to 0, stdin fd. Это тысячи примеров.

Без буферизации Libc или его реализации вы не можете делать то, что вы просите, - как только байт считывается из трубы, он принадлежит вам и уходит из трубы.

+0

спасибо за то, что я использую терминал ввода из stdin, а не для труб, которые экономят много времени. –

+0

Вы говорите, что функция: 'ungetc()' не будет нажимать символ на трубе? – user3629249

+0

Нет, я говорю ['ungetc'] (https://linux.die.net/man/3/ungetc) - это функция libc, которая работает с потоками' FILE * '- абстракцией libc поверх * фактические * файловые дескрипторы (например, ваши трубы). –

0

Я думаю, что есть две проблемы. Один из них заключается в том, что после того, как байт будет потреблен из потока, вы не сможете его оттолкнуть. Во-вторых, fgetc является блокирующей функцией, так что она будет ждать, пока данные не будут доступны, и вы не можете сообщить fgetc, чтобы вернуть, если нет (или даже вернуться после достижения таймаута).

Для первой проблемы вы можете обернуть соответствующий поток буфером, который затем должен использоваться во всей вашей программе и где будет выполняться предварительная выборка.

Для второй проблемы см., Например, это (или подобные) сообщения на non blocking I/O (пожалуйста, не забудьте пересмотреть ответ, если это полезно).