简体   繁体   English

无法从stdin正确读取

[英]Not reading from stdin properly

I'm trying to mimic the behavior of the unix utility cat, but when I call a command of the form: 我试图模仿unix实用程序cat的行为,但是当我调用以下形式的命令时:

cat file1 - file2 - file3 猫文件1-文件2-文件3

My program will output file1 correctly, then read in from stdin, then when I press EOF, it will print file 2 then file 3, without reading from stdin for the second time. 我的程序将正确输出file1,然后从stdin读取,然后按EOF,它将先打印文件2,然后打印文件3,而不是第二次从stdin读取。

Why might this be? 为什么会这样呢?

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

一方面,您不能期望它在关闭后可以从stdin读取:

            fclose(stdin);

fflush(stdin); is undefined behaviour, as is fflush on all files open only for input. 是未定义的行为,所有仅打开用于输入的文件上的fflush也是如此。 That's sort of like flushing the toilet and expecting the waste to come out of the bowl, because fflush is only defined for files open for output! 这有点像冲马桶和期待废出来的碗,因为fflush只为打开输出文件中定义! I would suggest something like for (int c = fgetc(stdin); c >= 0 && c != '\\n'; c = fgetc(stdin)); 我会建议for (int c = fgetc(stdin); c >= 0 && c != '\\n'; c = fgetc(stdin)); if you wish to discard the remainder of a line. 如果您希望舍弃行的其余部分。

Furthermore, fgetc returns int for a reason: Inside the int will be an unsigned char value or EOF . 此外, fgetc返回int是有原因的: int内部将是一个unsigned char值或EOF c should be an int, not a char . c应该是一个int,而不是char EOF isn't a character! EOF不是角色! It's a negative int value. 这是一个负int数值。 This differentiates it from any possible characters, because successful calls to fgetc will only return a positive integer rather than a negative EOF . 它将它与任何可能的字符区分开,因为成功调用fgetc只会返回一个正整数,而不是负EOF fputc expects input in the form of an unsigned char value. fputc期望以unsigned char值形式输入。 char isn't required to be unsigned . char不需要取消unsigned Providing your fgetc call is successful and you store the return value into an int , that int should be safe to pass on to fputc . 如果您的fgetc调用成功,并且将返回值存储到int ,则该int应该可以安全地传递给fputc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM