0

UNIX ユーティリティの cat の動作を模倣しようとしていますが、次の形式のコマンドを呼び出すと、次のようになります。

猫ファイル1 - ファイル2 - ファイル3

私のプログラムは file1 を正しく出力し、標準入力から読み込みます。EOF を押すと、標準入力から 2 回目の読み込みを行わずに、ファイル 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;
}
4

2 に答える 2

4

stdin1 つには、閉じた後に読み取ることができるとは期待できません。

            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 にする必要があります。キャラクターじゃない!マイナス値です。の呼び出しが成功すると、負の ではなく正の整数のみが返されるため、これにより、可能なすべての文字と区別されます。値の形式での入力を期待します。である必要はありません。呼び出しが成功し、戻り値を に格納すると、に安全に渡すことができます。intintunsigned charEOFccharEOFintfgetcEOFfputcunsigned charcharunsignedfgetcintintfputc

于 2013-01-20T23:36:37.707 に答える