0

我需要一些关于如何反转标准输入内容的建议。这是我处理反转标准输入的代码的一部分:

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除非(理论上)它已从输入文件重定向。而且由于没有办法(我知道,无论如何)知道已经发生了,所以不要费心去尝试。

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

#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

另一件要查看的是您的语句,它计算行数......

编辑:我还建议将标准输入设置为等于可以使用操作的变量。所以有类似temp = stdin这样的东西,你总是有那个初始的标准输入,你可以根据需要操作临时,如果你需要返回,你仍然有标准输入。

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

如果你仔细想想,你输入的那一行没有换行符,所以你的程序仍然认为有 0 行。所以我要么一开始就设置lineas = 1,或者如果你不知道是否会有任何内容,你可以检查其中是否有任何字符,所以在你的一段时间之后,或者在它的某个地方说if lineas == 0 then check for characters

要考虑的另一件事是所谓的幻数。这就是你的2048。我会考虑通过将 2048 设为“全局”变量来解决此问题。

建议流量

使用你的while陈述而不是你的for陈述。但是做,while(a != EOF)哪里是一个char所以继续做fgetc。然后只需将其放入数组末尾的大小为 2048 的字符数组中,然后向后工作(或者您可以将其放入从 0 到任意多个字符的字符数组中,然后有一个向后返回的 for 循环......那就是柜台会很方便)。但是你想要一个if a=='\n'then 向后打印行并将数组索引重置为 2048。我还建议有一个计数器来计算字符数,这样当你在数组中向后移动时,你不必经过整个事情直到2048-counter

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

于 2013-11-18T16:49:16.483 回答