没有正确读取标准输入

时间:2013-01-20 23:10:42

标签: c unix stdin eof cat

我正在尝试模仿unix实用程序cat的行为,但是当我调用表单的命令时:

cat file1 - file2 - file3

我的程序将正确输出file1,然后从stdin读入,然后当我按下EOF时,它将打印文件2然后文件3,而不是第二次从stdin读取。

为什么会这样?

    #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;
}

2 个答案:

答案 0 :(得分:4)

首先,您不能指望在关闭它之后能够从stdin阅读:

            fclose(stdin);

答案 1 :(得分:1)

fflush(stdin);是未定义的行为,对于仅为输入打开的所有文件都是fflush。这有点像冲洗马桶并期望废物从碗中出来,因为fflush仅定义为打开输出的文件!如果你想丢弃一行的剩余部分,我会建议像for (int c = fgetc(stdin); c >= 0 && c != '\n'; c = fgetc(stdin));这样的东西。

此外,fgetc会返回int,原因如下:int内的unsigned char值或EOFc应该是int,而不是charEOF不是角色!这是一个负int值。这会将其与任何可能的字符区分开来,因为成功调用fgetc只会返回正整数而不是负EOFfputc期望以unsigned char值的形式输入。 char不一定是unsigned。提供fgetc来电是成功的,您可以将返回值存储到int中,int应安全传递到fputc