Reputation: 12302
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
Upvotes: 0
Views: 5339
Reputation: 10305
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.
Upvotes: 1
Reputation: 66234
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)
Upvotes: 3
Reputation: 33273
You can't rewind stdin
!
You should revise your logic so you read until EOF
instead of trying to count the lines beforehand.
Upvotes: 4