c-在窗口中与管道一起使用时,STDIN、STDOUT没有流式传输正确的输出



平台:Windows

语言:C

我有两个程序:

  • 程序1使用fread读取二进制mode(_setmode(_fileno(stdin), _O_BINARY) ,_setmode(_fileno(stdout), _O_BINARY)中的.jpg文件,并使用fwrite将其输出到stdout
  • 程序2从stdout读取并输出到一个文件(read/write在二进制模式下完成(。但我可以看到输出图像被破坏了,和输入图像不一样。我在powershell中执行了program1.exe | program2.exe

但如果我写一个程序以二进制模式读取一个文件,并以二进制模式将其写入另一个文件中,那么输出是相同的。只有当我使用stdinstdout时才会出现问题。

程序1:

int main()
{
int mode, fd, ret;
errno_t err;
int a = _setmode(_fileno(stdin), _O_BINARY);
a = _setmode(_fileno(stdout), _O_BINARY);
//freopen("ooo", "wb", stdout);
//char in[4096];
char in[4096];
char o[100];
int size = sizeof(in);
FILE* fpIn, * fpOut, * fp3, * fin;
//int  a =_setmode(_fileno(stdin), _O_BINARY);
int x = sizeof(in);
fpOut = fopen("out", "wb");
//int bb = _setmode(_fileno(fpOut), _O_BINARY);
fin = fopen("pic.jpg", "rb");
//fin = fopen("in.txt", "rb");
//a = _setmode(_fileno(fin), _O_BINARY);
//int length = fread(&in, sizeof(in), 1, stdin);
int count = 0;

while ((count = fread(in, 1, sizeof(in), fin)) != 0)
{
fwrite(in, 1, count, stdout);
fflush(stdout);
}
fclose(fpOut);  
}

程序2:

int main()
{
int a = _setmode(_fileno(stdin), _O_BINARY);
a = _setmode(_fileno(stdout), _O_BINARY);
//freopen("ooo.txt", "wb", stdin);
char in[4096];

int o[100];
int size = sizeof(in);
FILE* fpIn, * fpOut, *fp3,*fin;
//int  a =_setmode(_fileno(stdin), _O_BINARY);
int x = sizeof(in);
fpOut = fopen("out", "wb");
//int bb = _setmode(_fileno(fpOut), _O_BINARY);
fin = fopen("pic.jpg", "rb");
a = _setmode(_fileno(fin), _O_BINARY);
//int length = fread(&in, sizeof(in), 1, stdin);
int count=0;
while ((count = fread(in, 1, sizeof(in), stdin)) != 0)
fwrite(in, 1, count, fpOut);

fclose(fpOut);
}

程序的要求是允许用户通过stdin输入任意输入并将其写入文件。

编辑

添加到评论中的地址对话,因为其相关性可能对OP很重要。注意当前编码cmd.exe程序的设置对于执行以下操作可能很重要你要的东西。该主题在中进行了讨论详细答案。和用来解释你为什么看到你所看到的。

您唯一声明的要求是"程序的要求是允许用户通过stdin输入任意输入并将其写入文件">

下面是一个使用freadfwrite的示例,但除非需要使用它们,否则请考虑一种更简单的方法。。。

借用注释,这个示例是最简单的实现,它完全符合您所描述的需要。(并使用Windows-10进行了测试。(

<ctrl-c>退出,然后读取文件out.txt。。。

int main(int argc, char *argv[]) {
int c = 0;
FILE *fp = fopen(".\out.txt", "w");
if(fp)
{
while( ( c = fgetc(stdin) ) != EOF ) 
{ 
fputc(c, stdout); //out to screen
fputc(c, fp); //to file
}
fclose(fp);    
}
return 0;
}

读取和输出二进制文件也很简单,只需更改fopen()中二进制读/写的参数,并指向要传输的图像:

当然,不需要使用<cntl-c>,程序将在文件复制完成后退出。

int main(int argc, char *argv[]) {
int c = 0;
FILE *fpIn = fopen(".\so_1.jpg", "rb");
FILE *fp = fopen(".\out.jpg", "wb");
if(fp)
{
while( ( c = fgetc(fpIn) ) != EOF ) { fputc(c, fp); }
fclose(fp);    
}
return 0;
}

如果需要使用fread/fwrite,那么这里有一个非常简单的例子,可以使用代码进行一些修改来完成完全相同的任务:(删除了对setmode的调用,in缓冲区的大小与它将包含的文件大小一致,删除了while循环,请参阅代码中的注释。(

int main(int argc, char *argv[]) 
{
int count = 0;
unsigned long len = fsize(".\so_1.jpg");//start by getting in file size
char in[len];//create buffer with exact count of bytes in file
FILE *fpIn = fopen(".\so_1.jpg", "rb");
if(fpIn)
{
FILE *fpOut = fopen(".\out.jpg", "wb");
if(fpOut)
{
count = fread(in, 1, sizeof(in), fpIn);//no need for while loop here, just check for > 0 
if(count > 0)
{
fwrite(in, 1, count, fpOut);
}
fclose(fpOut);
}
fclose(fpIn);
}
return 0;
}
unsigned long fsize(char* file)
{
if(!file) return 0UL;
FILE * f = fopen(file, "r");
if(!f) return 0UL;
if(fseek(f, 0, SEEK_END) != 0) return 0UL;
unsigned long len = (unsigned long)ftell(f);
fclose(f);
return len;
}

相关内容

最新更新