C 未正确读取标准数据

C 未正确读取标准数据,c,unix,stdin,eof,cat,C,Unix,Stdin,Eof,Cat,我试图模仿unix实用程序cat的行为,但当我调用以下形式的命令时: cat文件1-文件2-文件3 我的程序将正确输出文件1,然后从标准输入中读取,然后当我按EOF时,它将打印文件2,然后打印文件3,而不会第二次从标准输入中读取 为什么会这样 #include <stdio.h> #include <stdlib.h> #include <string.h> #define ASCII_LENGTH 255 int printfile(FILE *so

我试图模仿unix实用程序cat的行为,但当我调用以下形式的命令时:

cat文件1-文件2-文件3

我的程序将正确输出文件1,然后从标准输入中读取,然后当我按EOF时,它将打印文件2,然后打印文件3,而不会第二次从标准输入中读取

为什么会这样

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ASCII_LENGTH 255
int printfile(FILE *source, int N);

int main(int argc, char *argv[])
{
    int currentarg = 1; //the argument number currently being processed

    FILE *input_file;
    //if there are no arguments, dog reads from standard input
    if(argc == 1 || currentarg == argc)
    {
        input_file = stdin;
        printfile(input_file,0);
    }
    else
    {
        int i;
        for(i = currentarg; i < argc; i++)
        {
            printf("%d      %s\n",i,argv[i]);
            //if file is a single dash, dog reads from standard input
            if(strcmp(argv[i],"-") == 0)
            {
                input_file = stdin;
                printfile(input_file,0);
                fflush(stdin);
                fclose(stdin);
                clearerr(stdin);
            }
            else if ((input_file = fopen(argv[i], "r")) == NULL)
            {
                fprintf(stderr, "%s: %s: No such file or directory\n", argv[0], argv[i]);
                return 1;
            }
            else
            {
                printfile(input_file,0);
                fflush(input_file);
                fclose(input_file);
                clearerr(input_file);
            }
        }
    }
    return 0;
}

int printfile(FILE *source, int N) 
{
    //used to print characters of a file to the screen
    //characters can be shifted by some number N (between 0 and 25 inclusive)
    char c;
    while((c = fgetc(source)) != EOF)
    {
        fputc((c+N)%ASCII_LENGTH,stdout);
    }
    printf("*****    %c     %d",c,c==EOF);
    return 0;
}
#包括
#包括
#包括
#定义ASCII_长度255
int printfile(文件*源,int N);
int main(int argc,char*argv[])
{
int currentarg=1;//当前正在处理的参数号
文件*输入文件;
//若并没有参数,dog将从标准输入读取
如果(argc==1 | | currentarg==argc)
{
输入文件=stdin;
打印文件(输入文件,0);
}
其他的
{
int i;
对于(i=currentarg;i
首先,您不能期望在关闭stdin后能够读取它:

            fclose(stdin);

首先,您不能期望在关闭stdin后能够读取它:

            fclose(stdin);
fflush(stdin)是未定义的行为,就像所有仅为输入而打开的文件上的
fflush
一样。这有点像冲厕,期待垃圾从碗里出来,因为
fflush
只为打开输出的文件定义!我建议使用类似的
for(intc=fgetc(stdin);c>=0&&c!='\n';c=fgetc(stdin))如果要放弃行的剩余部分

此外,
fgetc
返回
int
的原因是:
int
内部将是一个
无符号字符
值或
EOF
c
应该是int,而不是
char
<代码>EOF
不是字符!这是一个负的
int
值。这将它与任何可能的字符区分开来,因为成功调用
fgetc
将只返回正整数,而不是负的
EOF
fputc
要求以
unsigned char
值的形式输入
char
不需要是
无符号的
。如果您的
fgetc
调用成功,并且您将返回值存储到
int
中,
int
应该可以安全地传递到
fputc
fflush(stdin)是未定义的行为,就像所有仅为输入而打开的文件上的
fflush
一样。这有点像冲厕,期待垃圾从碗里出来,因为
fflush
只为打开输出的文件定义!我建议使用类似的
for(intc=fgetc(stdin);c>=0&&c!='\n';c=fgetc(stdin))如果要放弃行的剩余部分


此外,
fgetc
返回
int
的原因是:
int
内部将是一个
无符号字符
值或
EOF
c
应该是int,而不是
char
<代码>EOF
不是字符!这是一个负的
int
值。这将它与任何可能的字符区分开来,因为成功调用
fgetc
将只返回正整数,而不是负的
EOF
fputc
要求以
unsigned char
值的形式输入
char
不需要是
无符号的
。如果您的
fgetc
调用成功,并且您将返回值存储到
int
中,
int
应该可以安全地传递到
fputc

,我想您不会考虑查看
fopen
失败,原因除了
enoint
。检查文档中的
strerror
perror
。不要编造理由:让系统告诉你。你关闭
stdin
,难怪下次它会关闭;-)我不认为您考虑过查看
fopen
失败的原因有很多,除了
enoint
。检查文档中的
strerror
perror
。不要编造理由:让系统告诉你。你关闭
stdin
,难怪下次它会关闭;-)