0

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

猫文件1-文件2-文件3

我的程序将正确输出 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;
}
4

2 回答 2

4

stdin一方面,您不能指望在关闭它后能够读取:

            fclose(stdin);
于 2013-01-20T23:12:51.430 回答
1

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

此外,fgetc返回int是有原因的:在内部int将是一个unsigned char值或EOFc应该是 int,而不是char. EOF不是人物!这是一个负值int。这将它与任何可能的字符区分开来,因为成功调用fgetc只会返回一个正整数而不是一个负整数EOFfputc期望以值的形式输入unsigned charchar不需要是unsigned. 假设您的fgetc调用成功并且您将返回值存储到int中,int应该可以安全地传递给fputc.

于 2013-01-20T23:36:37.707 回答