2013-11-18 4 views
0

Мне нужен совет по изменению содержимого stdin. Это часть моего кода, который обрабатывает реверсирования STDIN:Сторнирование stdin в 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 
+0

Что вы видите, когда вы проследите через ваш код в отладчике? – JoelFan

+2

Невозможно перемотать stdin. Вам нужно прочитать весь файл, а затем пройти через буфер, в который вы его прочитали. –

+0

Я не уверен, как я могу запустить свою программу из отладчика, используя echo "text" | myprogram, но я рассмотрю его. Благодаря! – hugo19941994

ответ

1

Во-первых, перемотка 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; 
} 

Довольно уверен, что будет делать то, что вы ищете (или близко к нему, во всяком случае)

4

Вы не можете перемотать stdin!

Вы должны пересмотреть свою логику, чтобы читать до EOF вместо того, чтобы пытаться считать строки заранее.

+0

Спасибо! Я изменю его – hugo19941994

1

Другое дело смотреть на ваше утверждение, что подсчитывает строки ...

EDIT: Я хотел бы также предложить установки стандартного ввода, равную переменной, которую можно использовать манипулировать. Так что есть что-то вроде temp = stdin, поэтому у вас всегда будет этот начальный stdin, и temp вы можете манипулировать по мере необходимости, и если вам нужно вернуться, у вас все еще есть stdin.

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

Если вы об этом думаете, что линия, что вы положили в не имеет символ новой строки, так что ваша программа все еще думает, что есть 0 линии. Поэтому я бы либо изначально установил lineas = 1, либо если вы не знаете, будет ли какой-либо контент, который вы можете проверить, чтобы увидеть, есть ли в нем какие-либо символы, поэтому после вашего времени или где-то в нем говорят if lineas == 0 then check for characters

Еще одна вещь, которую следует рассмотреть, это то, что называется Magic Numbers. Это то, что ваш 2048. Я хотел бы изучить это, сделав 2048 «глобальной» переменной.

Предложенное поток

Используйте while заявление вместо вашего for заявление. Но делайте, while(a != EOF) где a - char, поэтому продолжайте делать fgetc. Затем просто поместите его в массив символов размером 2048 НА КОНЕЦ массива и работайте назад (или вы можете поместить его в массив символов от 0 до любого числа символов, а затем цикл for, который идет назад ... это где счетчик будет удобен). Но вы хотите иметь if a=='\n', а затем распечатать строку назад и сбросить индекс массива до 2048. Я также предложил бы иметь счетчик, который будет подсчитывать количество символов, чтобы при движении назад в массиве вам не нужно проходить все это только до 2048-counter.

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

Смежные вопросы