чтение до EOF от стандартного ввода в c - PullRequest
0 голосов
/ 03 марта 2012

Я использую машину Unix и пытаюсь читать с консоли, пока не будет достигнут EOF (поставляю Ctrl + D). Я использую fread_unlocked, для чтения на входе он выводит корректность чтения целых чисел, но вместо нормального выхода дает ошибку сегментации на EOF Как мне изменить мой код так, чтобы он вел себя так, как ожидалось?

int MAXX = 10000000;
char *ipos, InpFile[MAXX];

inline int input_int(int flag=0)
{
  while(*ipos<=32)
    ++ipos;
 if(flag)
    return(*ipos++-'0');
 LL x=0,neg=0;
 char c;
 while(true)
  {
    c=*ipos++;
    if(c=='-')
        neg=1;
    else
    {
        if(c<=32)
         return neg?-x:x;x=(x<<1)+(x<<3)+c-'0';
    }
  }
 }
int main()
{
   ipos = InpFile;
   fread_unlocked(InpFile, MAXX, 1, stdin);
   while(true){
   int n = input_int();
   printf("%d\n",n);
   }
   return 0;
}   

Мой ввод с консоли: 3 4 5 6Ctrl+D Вывод, который я получаю сейчас: 3 4 5 6 Segmentation Error Ожидаемый результат: 3 4 5 6 Спасибо.

Ответы [ 2 ]

3 голосов
/ 03 марта 2012

fread_unlocked возвращает количество байтов, которые были фактически прочитаны. Вам нужно принять это возвращаемое значение и убедиться, что вы никогда не пытаетесь использовать больше, чем столько символов из InpFile. Например, если вы объявляете max_ipos в глобальной области видимости, вы можете написать:

size_t bytes_read = fread_unlocked(InpFile, 1, MAXX, stdin);
// check for errors
max_ipos = &InpFile[bytes_read];

, а затем input_int потребуется определить, когда ipos == max_ipos, и завершить работу перед чтением *ipos.

Отредактировано, чтобы добавить: Обратите внимание, что (по предложению Джонатана Леффлера) я изменил порядок аргументов 1 и MAXX на fread_unlocked. Это потому, что вы хотите читать объекты размером 1, а не объекты размером MAXX.

Кстати, это:

inline int input_int(int flag=0)

не является допустимым C. Значения по умолчанию для аргументов - это C ++. (Может быть, есть компиляторы C, которые поддерживают его как расширение & mdash; я не знаю & mdash; но, безусловно, есть компиляторы C, которые этого не делают.)

0 голосов
/ 03 марта 2012

Ваш код очень грязный код, и каждый, кто его прочитает, обязательно будет сбит с толку, поэтому я очищаю ваш код:

#include <stdio.h>
#include <iostream>
using namespace std;
int MAXX = 10000000;
char x = 0 ; 
char *ipos = &x, InpFile[10000000];

inline int input_int(int flag=0){
  while( *::ipos <= 32 )
    ++::ipos;
  if(flag)
     return(*::ipos++) -'0';
  char x = 0 , neg = 0;
  char c = ' ';
  while ( true ) {
      c = (*::ipos++);
      if(c == '-')
          neg = 1;
      else {
          if(c <= 32)
              return neg ? -x : x; 
          x = (x << 1) + (x << 3) + c -'0';
      }
  }
}

int main(){
   ipos = InpFile;
   fread_unlocked(InpFile, MAXX, 1, stdin);
   while ( true ) {
       int n = input_int();
       printf( " %d \n " , n);
   }
   return 0;
}   

Кстати, вы не упомянули о работе вашей программы. Другая проблема: вы не инициализировали указатель ipos. Если вы хотите работать с указателями, не забудьте инициализировать их.

...