在C中反转stdin

时间:2013-11-18 16:22:53

标签: c stdin reversing

我需要一些关于如何反转stdin内容的建议。这是我的代码中处理反转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

3 个答案:

答案 0 :(得分:4)

您无法快退stdin

您应修改逻辑,以便阅读EOF,而不是事先计算行数。

答案 1 :(得分:2)

首先,除非(理论上)从输入文件重定向,否则不支持倒回stdin。而且由于无法知道(无论如何)知道已经发生的事情,所以不要费心去尝试。

这就是说,与显然流行的观点相反,你不必缓冲整个输入。你仍然可以一次缓冲它:

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

非常肯定会做你正在寻找的东西(或者接近它,无论如何)

答案 2 :(得分:1)

要看的另一件事是你的陈述会计算线......

编辑:我还建议将stdin设置为可以使用操作的变量。所以有类似temp = stdin的东西,所以你总是会有那个初始的stdin,而你可以根据需要进行操作,如果你需要回去,你仍然有stdin。

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

如果你考虑一下,你输入的那一行没有换行符号,所以你的程序仍然认为有0行。所以我要么最初设置lineas = 1,要么你不知道是否有任何内容,你可以查看是否有任何字符,所以在你的时间或其中的某个地方说{ {1}}

另一件需要考虑的事情是 Magic Numbers 。这就是你的2048。我会考虑通过使2048成为“全局”变量来解决这个问题。

建议的流程

使用您的if lineas == 0 then check for characters语句代替while语句。但是,for其中a是while(a != EOF),所以继续char。然后将它放入数组末尾大小为2048的字符数组中,并向后工作(或者你可以将它放入字符数组中,从0到多个字符,然后有一个for循环向后...这是柜台便利的地方)。但是你想要一个fgetc然后向后打印该行并将数组索引重置为2048.我还建议有一个计数器来计算字符数,这样当你在数组中向后移动时你就不会必须经历整个事情,直到if a=='\n'

这可以帮助您更简洁的流程。您也不需要那么多代码。