2012-03-03 3 views
0

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

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 Спасибо.

ответ

3

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.

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

Кстати, это:

inline int input_int(int flag=0) 

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

+2

На самом деле порядок аргументов 'fread()' (и, следовательно, 'fread_unlocked()' are 'size_t fread (void * ptr, size_t size, size_t nitems, FILE * stream);', поэтому 'fread() 'call будет возвращать 0, если пользователь не наберет символы« MAXX »(которых мы можем быть уверены, не произойдет, так как« MAXX »составляет 10 миллионов), возвращаемое значение из' fread() 'будет равно нулю. ('1, MAXX'), а затем вы получите полезную информацию. И да, я все еще смотрю на страницу man для' fread() ', прежде чем использовать ее каждый раз. –

+0

@JonathanLeffler: Это отличный момент. обновил мой ответ, спасибо! – ruakh

+0

спасибо за решение :) – pranay

0

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

#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. Если вы хотите работать с указателями, не забудьте инициализировать их.

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