Pergunta
Preciso de alguns conselhos sobre como reverter o conteúdo do stdin.Esta é a parte do meu código que trata da reversão do 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;
}
Também tenho um arquivo .txt chamado exemplo1 com o seguinte conteúdo:
LINE 1.1
LINE 1.2
LINE 1.4
Este código funciona quando eu executo ./myprogram < example1.txt
.Ele produz
1.1 ENIL
2.1 ENIL
4.1 ENIL
Mas, se eu executar echo "This text should be reversed" | ./myprogram
ele produz:
(
É isso.Um colchete aberto.Descobri que se eu omitir a parte do meu código que conta as linhas e apenas disser manualmente que há 1 linha, isso funciona (para 1 linha, é claro).
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;
}
Agora produz
desrever eb dluohs txet sihT
Solução
Primeiro, retrocedendo stdin
não é suportado a menos que (em teoria) tenha sido redirecionado de um arquivo de entrada.E como não há como (pelo menos eu sei) saber o que aconteceu, não se preocupe em tentar.
Dito isto, ao contrário do que aparentemente é a opinião popular, você não precisa armazenar em buffer toda a entrada.Você ainda pode armazenar em buffer linha por vez:
#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;
}
Tenho certeza de que fará o que você está procurando (ou perto disso, pelo menos)
Outras dicas
Você não pode retroceder stdin
!
Você deve revisar sua lógica para ler até EOF
em vez de tentar contar as linhas de antemão.
Outra coisa a se observar é a sua declaração que conta linhas...
EDITAR:Eu também sugeriria definir stdin igual a uma variável que você pode usar para manipular.Então tenha algo como temp = stdin
então você sempre terá aquele stdin inicial e a temperatura que você pode manipular conforme necessário e, se precisar voltar, ainda terá o stdin.
while ((a=fgetc(stdin)) !=EOF)
{
if (a=='\n')
lineas++;
}
Se você pensar bem, aquela linha que você inseriu não tem um caractere de nova linha, então seu programa ainda pensa que há 0 linhas.Então eu definiria inicialmente lineas = 1
ou se você não sabe se haverá ou não algum conteúdo, você pode verificar se há algum personagem nele, então depois de um tempo, ou em algum lugar nele, diga if lineas == 0 then check for characters
Outra coisa a considerar é algo chamado Números Mágicos.Isso é o que é o seu 2048.Eu tentaria consertar isso, tornando 2048 uma variável 'global'.
Fluxo sugerido
Use o seu while
declaração em vez de sua for
declaração.Mas faça, while(a != EOF)
onde a é um char
então continue fazendo fgetc
.Em seguida, basta colocá-lo em uma matriz de caracteres de tamanho 2048 NO FINAL da matriz e trabalhar de trás para frente (ou você pode colocá-lo na matriz de caracteres de 0 a quantos caracteres tiver um loop for que retrocede... isto é onde um contador seria útil).Mas você quer ter um if a=='\n'
em seguida, imprima a linha ao contrário e redefina o índice da matriz para 2048.Eu também sugeriria ter um contador que contasse o número de caracteres para que, ao retroceder na matriz, você não precise percorrer tudo apenas até 2048-counter
.
Isso deve ajudá-lo com um fluxo mais conciso.Você também não precisará de tanto código.