Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在windows中与管道一起使用时,STDIN、STDOUT不正确输出_C_Stdout_Stdin_Fwrite_Fread - Fatal编程技术网

C 在windows中与管道一起使用时,STDIN、STDOUT不正确输出

C 在windows中与管道一起使用时,STDIN、STDOUT不正确输出,c,stdout,stdin,fwrite,fread,C,Stdout,Stdin,Fwrite,Fread,平台:Windows 语言:C 我有两个项目: 程序1使用fread读取二进制模式下的.jpg文件(\u setmode(\u fileno(stdin),\u O\u binary),\u setmode(\u fileno(stdout),\u O\u binary),并将using fwrite输出到stdout 程序2从标准输出读取并输出到一个文件(read/write以二进制模式完成)。但我可以看到输出图像已损坏,与输入图像不一样。 我在powershell中执行了program1.

平台:Windows

语言:C

我有两个项目:

  • 程序1使用fread读取二进制
    模式下的
    .jpg
    文件(\u setmode(\u fileno(stdin),\u O\u binary),\u setmode(\u fileno(stdout),\u O\u binary)
    ,并将using fwrite输出到stdout
  • 程序2从标准输出读取并输出到一个文件(
    read/write
    以二进制模式完成)。但我可以看到输出图像已损坏,与输入图像不一样。 我在powershell中执行了
    program1.exe | program2.exe
但是,如果我编写一个程序以二进制模式读取一个文件,并以二进制模式将其写入另一个文件,那么输出是相同的。只有当我使用
stdin
stdout
时,问题才会出现

方案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);
}
程序的要求是允许用户通过标准输入法输入任意输入,并将其写入文件。

EDIT

添加到评论中,以说明对话的相关性 对OP很重要。注意当前编码 您的
cmd.exe
程序的设置对于执行某些操作可能很重要 您要求的内容。该主题在和中进行了讨论 用来解释你为什么看到你所看到的

您唯一声明的要求是“程序的要求是允许用户通过标准输入法输入任意输入,并将其写入文件。”

一个例子,使用代码> Frad 和 fWord,但除非您需要使用这些代码,否则请考虑更简单的方法…

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

退出,然后读取文件
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()
中用于二进制读取/写入的参数,并指向要传输的图像:

当然不需要使用
,文件复制完成后程序将退出

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
的调用,缓冲区中的
大小与它将包含的文件相同,删除了
循环,请参见代码注释中的内容。)


while((c=fgetc(stdin))!=EOF{fputc(c,stdout);}
不起作用吗?我很高兴我不必使用Windows。在程序2中,您不需要使用stdout或打开fpIn。(1)所有注释掉的代码都很混乱。粘贴您实际用于生成所描述结果的代码。(2)如果忽略系统库函数的返回值,许多编译器会抱怨。您可以通过将该值指定给从未使用过的变量来抑制警告,但这不是问题的关键:问题是确保函数未指示错误,并采取措施(至少记录错误)如果是这样,特别是如果你怀疑结果。谢谢你的回复。我想从STDIN中写入任意数据,当SOY1.JPG被读写到Out.jPG时,这些都不会有问题,但是当我通过STDIN传递这些相同的输入时,输出将不匹配。☻(ALT+NUMKEY2)作为标准输入,out.txt将不包含☻ 相反,它将包含一些无效字符或无字符(由于编码不同),通过some.jpg作为输入可以观察到相同的情况stdin@Brain-请记住,
无符号字符
字节
)可以在
标准输出中可见的可打印字符范围内表示。简单地说,文本流可以用几种方式编码,但二进制数据是二进制数据。您的示例输入了
的文本表示形式☻(ALT+NUMKEY2)
,但它可以是(例如
ASCII
unicode
wide char
)每一个都导致一个对应的不同的二进制流。这可能就是为什么
input!=output
ASCII a
编码例如是
0x41
,而
EBCDIC
编码是
0xC1
导致不同的二进制值。请参阅我答案顶部的更新注释。
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;
}