Reversing stdin in C

强颜欢笑 提交于 2019-12-13 04:36:52

问题


I need some advice on how to reverse the contents of stdin. This is the part of my code which handles reversing 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;
}

I also have a .txt file called example1 with the following contents:

LINE 1.1
LINE 1.2

LINE 1.4

This code works when I execute ./myprogram < example1.txt. It outputs

1.1 ENIL
2.1 ENIL

4.1 ENIL

But, if I execute echo "This text should be reversed" | ./myprogram it outputs:

(

That's it. An open bracket. I've discovered that if I omit the part of my code which counts lines and just manually say there is 1 line it works (for 1 line of course).

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

It now outputs

desrever eb dluohs txet sihT

回答1:


First, rewinding stdin isn't supported unless (in theory) it has been redirected from an input file. And since there is no way (I know of, anyway) of knowing that has happened, don't bother trying it.

That said, contrary to what is apparently popular opinion, you do not have to buffer the entire input. You can still buffer it line-at-a-time:

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

Pretty sure that will do what you're looking for (or close to it, anyway)




回答2:


You can't rewind stdin!

You should revise your logic so you read until EOF instead of trying to count the lines beforehand.




回答3:


Another thing to look at is your statement that counts lines...

EDIT: I would also suggest setting stdin equal to a variable that you can use an manipulate. So have something like temp = stdin so you will always have that initial stdin, and temp you can manipulate as needed, and if you need to go back, you still have stdin.

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

If you think about it, that line that you put in doesn't have a new line character, so your program still thinks there are 0 lines. So I would either initially set lineas = 1 or if you don't know whether or not there will be any content you can check to see if there are any characters in it, so after your while, or someplace in it say if lineas == 0 then check for characters

Another thing to consider is something called Magic Numbers. That is what your 2048 is. I would look into fixing that, by making 2048 a 'global' variable.

Suggested flow

Use your while statement instead of your for statement. But do, while(a != EOF) where a is a char so keep doing fgetc. Then just put it into a character array of size 2048 AT THE END of the array, and work backwards(or you could put it into the character array from 0 to however many characters then have a for loop that goes backwards...that is where a counter would be handy). But you want to have an if a=='\n' then print the line backwards and reset the array index to 2048. I would also suggest having a counter that would count the number of characters so that when going backwards in the array you don't have to go through the whole thing just until 2048-counter.

This should help you out with a more concise flow. You also won't need as much code.



来源:https://stackoverflow.com/questions/20052657/reversing-stdin-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!