C从命名管道读取和写入

时间:2013-11-23 08:11:28

标签: c named-pipes

我最终想要一个this problem的解决方案,但是在真正的一步前进 - 后退两步方式中编程,我已经被简化为弄清楚为什么我甚至不能写一个字符到一个命名管道然后返回相同的字符。这是一个简单的MWE脚本,我很遗憾地得到了附带的输出:

MWE:

#include <stdio.h>
#include <fcntl.h>
#define PIPE_PATH "testpipe"

int main( int argc, char *argv[] ) {
   int fd;
   FILE *fp;
   char c;
   int result;
   int contingency;

   //Initialize it for debugging purposes
   c = 0;
   contingency = 0;

   if ( atoi ( argv [ 1 ] ) == 1 )
   {
      printf ("Writer [%s]\n", argv[1]);

      mkfifo ( PIPE_PATH, 0666 );

      fd = open ( PIPE_PATH, O_WRONLY );
      c = getchar();
      printf ( "[%d] [%s]\n", c, &c );

      if ( ( result = write ( fd, &c, 1 ) ) == -1)
      {
         fprintf ( stderr, "error writing to pipe\n" );
         return -1;
      }

      close(fd);
   }
   else if ( atoi ( argv [ 1 ] ) == 2 )
   {
      printf ( "Reader [%s]\n", argv[1] );

      fp = fopen( PIPE_PATH, "r" );
      while ( contingency < 3 && ( c = getc ( fp ) ) != EOF )
      { //contingency set to 3 to avoid infinite loop
         c = getc ( fp );
         putchar ( c );
         printf ( "[%d]\n", c ); //don't print c as a string or the shell will go nuts

         printf ( "\n" );
         contingency++;
      }
      fclose ( fp );

      unlink( PIPE_PATH );
   }

   return 0;
}

输出:

Writer [1]
q
[113] [q]
....
Reader [2]
�[255]
�[255]
�[255]

出于某种原因,我得到一个问题符号卡在六边形中,但是在vim中看起来像y(伽玛?),上面有一个umlat。由于与此字符关联的ASCII代码为255,因此我假设管道未按预期工作并返回可能的最高值。有人可以告诉我发生了什么事,因为我在生命的最后6个小时里没有完成任何事情吗?

1 个答案:

答案 0 :(得分:7)

第一个错误

这里的一个大问题......

char c = getc(fp);

看到了吗?这是一个大问题。为什么?我们来看看getc() ...

的定义
int getc(FILE *stream);

是的,它会返回int而不是char,而重要,其中包含大写 I 和粗体字。 getc()函数(或宏)使用EOF发出EOF信号,通常为-1,因此在0xff存储时会变为char

始终将intgetc()一起使用。

int c = getc(fp);
if (c == EOF) {
    ...
}

第二个错误

那么,我们为什么要获得EOF?因为getc()被称为两次而不是一次......

while ((c = getc(fp)) != EOF) {
    c = getc(fp); // <-- should not be there
    ...
}

第三个错误

这段代码也错了:

char c = ...;
printf("[%d] [%s]\n", c, &c);

是的,&c的类型为char *,但这并不意味着您可以使用%s打印出来。 %s说明符严格用于NUL终止的字符串。使用%c,或继续使用%s并NUL终止您传递的字符串。

char c = ...;
printf("[%d] [%c]\n", c, c);

或者...

char c = ...;
printf("[%d] [%s]\n", c, (char[]){c, '\0'});