Реверсивный ввод в C
Мне нужен совет о том, как отменить содержимое стандартного ввода. Это часть моего кода, которая обрабатывает реверсирование стандартного ввода:
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;
}
У меня также есть.txt файл с именем example1 со следующим содержимым:
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 ответа
Сначала перематывать 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;
}
Уверен, что это сделает то, что вы ищете (или в любом случае близко к этому)
Вы не можете перематывать stdin
!
Вы должны пересмотреть свою логику, чтобы вы читали до EOF
вместо того, чтобы пытаться считать строки заранее.
Еще одна вещь, на которую стоит обратить внимание, это ваше утверждение, которое считает строки...
РЕДАКТИРОВАТЬ: Я бы также предложил установить stdin равным переменной, которую вы можете использовать манипулировать. Так что есть что-то вроде temp = stdin
таким образом, у вас всегда будет этот начальный stdin, и 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'
затем выведите строку в обратном направлении и сбросьте индекс массива до 2048. Я также предложил бы иметь счетчик, который бы подсчитывал количество символов, чтобы при возврате в массиве вам не приходилось проходить все это до 2048-counter
,
Это должно помочь вам с более кратким потоком. Вам также не понадобится так много кода.