0

stdin の内容を元に戻す方法についてアドバイスが必要です。これは、標準入力の反転を処理するコードの一部です。

int reversestdin(FILE *file)
{
    int a, b;
    int lineas=0;
    while ((a=fgetc(stdin)) !=EOF)
    {
        if (a=='\n')
            lineas++;
    }
    for(b=0; b<lineas; b++)
    { 
        rewind(stdin);
        int d,len, e;
        char str[2048], *ptr;
        for(e=0; e<=b; e++)
        { 
            fgets(str, 2048, stdin);
        }
        ptr=str;
        for(d=0; d<2048; d++)
        {
            if(*ptr=='\n')  break;
            if(*ptr=='\0')  break;
            ptr++;
        }
        len=d;
        ptr--;
        for(d=len; d>0; d--)
        {
            printf("%c", *ptr--);
        }

        printf("\n");
    }
    return 0;
}

次の内容の example1 という .txt ファイルもあります。

LINE 1.1
LINE 1.2

LINE 1.4

このコードは、実行すると機能し./myprogram < example1.txtます。出力します

1.1 ENIL
2.1 ENIL

4.1 ENIL

しかし、実行すると次のようecho "This text should be reversed" | ./myprogramに出力されます。

(

それでおしまい。開いたブラケット。行を数えるコードの部分を省略し、手動で1行あると言うだけで機能することを発見しました(もちろん1行の場合)。

int reversestdin(FILE *file)
{
    int a, b;
    int lineas=1;
    //while ((a=fgetc(stdin)) !=EOF)
    //{
        //if (a=='\n')
            //lineas++;
    //}
    for(b=0; b<lineas; b++)
    { 
        rewind(stdin);
        int d,len, e;
        char str[2048], *ptr;
        for(e=0; e<=b; e++)
        { 
            fgets(str, 2048, stdin);
        }
        ptr=str;
        for(d=0; d<2048; d++)
        {
            if(*ptr=='\n')  break;
            if(*ptr=='\0')  break;
            ptr++;
        }
        len=d;
        ptr--;
        for(d=len; d>0; d--)
        {
            printf("%c", *ptr--);
        }

        printf("\n");
    }
    return 0;
}

出力するようになりました

desrever eb dluohs txet sihT
4

3 に答える 3

4

巻き戻しはできませんstdin

EOF事前に行数を数えようとするのではなく、最後まで読むようにロジックを修正する必要があります。

于 2013-11-18T16:30:29.623 に答える
3

まず、stdin(理論的には) 入力ファイルからリダイレクトされていない限り、巻き戻しはサポートされていません。そして、それが起こったことを知る方法がないので(とにかく私は知っています)、わざわざ試してはいけません.

とはいえ、明らかに一般的な意見とは反対に、入力全体をバッファリングする必要はありません。一度に1行ずつバッファすることもできます:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int buffer[2048], ch, lines=0, i=0;
    do
    {
        ch = fgetc(stdin);
        if ((ch == '\n') || 
            (ch == EOF && i > 0) || 
            (i == (sizeof(buffer)/sizeof(*buffer)-1)))
        {
            ++lines;
            while (i != 0)
                fputc(buffer[--i], stdout);
            fputc('\n', stdout);
        }
        else
        {
            buffer[i++] = ch;
        }
    } while (ch != EOF);

    return 0;
}

それがあなたが探していることをすることを確信しています(またはとにかくそれに近い)

于 2013-11-18T16:54:18.000 に答える
1

もう1つ確認すべきことは、行を数えるステートメントです...

編集: stdin を、操作を使用できる変数に等しく設定することもお勧めします。そのtemp = stdinため、必要に応じて操作できる最初の標準入力と一時を常に保持し、戻る必要がある場合でも標準入力を使用できます。

while ((a=fgetc(stdin)) !=EOF)
    {
        if (a=='\n')
            lineas++;
    }

考えてみると、入力した行には改行文字がないため、プログラムはまだ行が 0 であると認識しています。だから私は最初に設定するかlineas = 1、コンテンツがあるかどうかわからない場合は、その中にキャラクターがいるかどうかを確認できるので、しばらくして、またはその中のどこかに言うif lineas == 0 then check for characters

考慮すべきもう 1 つのことは、マジック ナンバーと呼ばれるものです。それがあなたの2048です。2048 を「グローバル」変数にすることで、それを修正することを検討します。

推奨フロー

あなたのwhile声明の代わりにあなたの声明を使用してくださいfor。しかし、while(a != EOF)a が a である場合、 do を実行しchar続けfgetcます。次に、それを配列の最後でサイズ2048の文字配列に入れ、逆方向に作業します(または、文字配列に0から文字数まで入れて、逆方向に進むforループを作成できます...つまりカウンターが便利な場所)。ただしif a=='\n'、行を逆方向に出力し、配列インデックスを 2048 にリセットする必要があります。また、文字数をカウントするカウンターを用意することをお勧めします。これにより、配列を逆方向に移動するときに、全体ちょうどまで2048-counter

これにより、より簡潔なフローが得られるはずです。また、それほど多くのコードは必要ありません。

于 2013-11-18T16:49:16.483 に答える