Вопрос

Мне нужен совет, как отменить содержимое стандартного ввода.Это часть моего кода, которая обрабатывает реверсирование стандартного ввода:

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
Это было полезно?

Решение

Сначала перемотка 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 вместо того, чтобы пытаться заранее посчитать строки.

Еще одна вещь, на которую стоит обратить внимание, - это ваш оператор, который считает строки...

РЕДАКТИРОВАТЬ:Я бы также предложил установить стандартный ввод равным переменной, которой вы можете манипулировать.Итак, сделайте что-то вроде 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.

Это должно помочь вам сделать поток более кратким.Вам также не понадобится столько кода.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top