Требуется помощь в отношении ошибки сегментации в указателе файла - PullRequest
0 голосов
/ 06 июня 2011

У меня есть программа 'C', которая столкнулась со странной проблемой .. Я получаю ошибку сегментации в строке, содержащей "feof (fp)" .. Я пытаюсь запустить на Linux ..

Я даже использовал команду GDB, чтобы отследить программу .. Но это было бесполезно ..

Проверьте мой пример кода ..

char buf[2000],str[15],lno[5],def[15],ref[15],tmp[15],ch,ifile[20],ofile[20];

int i,j,oldi,count,c,r,d,f,t,lc=0;



FILE *fp=NULL,*fpo=NULL;

void xyzstart()
{
/*
*Some operation that is not at all concerned with the file
*
*/
}

int main()

{

printf("Enter the name of the input file\n");

gets(ifile);



fp=fopen(ifile,"r");
if(fp==NULL)

{

printf("Error");

exit(0);

}



printf("Enter the name of the output file\n");
gets(ofile);

fpo=fopen(ofile,"w");


if(fpo==NULL)

{

printf("Output file couldn't be opened\n");

exit(0);

}




while(!feof(fp))

{

fgets(buf,sizeof(buf),fp);

count++;  //Count the number of lines in a file

}



rewind(fp); //move the file pointer to the beginning of the file



while(!feof(fp)) //Error is here!! Segmentation fault (Core Dumped)!!

{

clear();  //User defined function which clears all the memory

if(count==lc)

{

nodef();  //User defined function which doesn't reads from or writes into a file

noref();  //User defined function which doesn't reads from or writes into a file

print();  //User defined function which writes the values to output file

break;

}



fgets(buf,sizeof(buf),fp); 

{

i=0;

lc++;


    while(buf[i]!=' ') //read until it encounters a space..

      {

      lno[i]=buf[i];

      i++;

      }

    lno[i]='\0';

//puts(lno);///

    }



i++;

oldi=i;

ch=buf[i];

switch(ch)

{

case 'x': xyzstart(); break;

default: printf("Nothing found");
}

}



fclose(fpo);

fclose(fp);

return 0;

}

Я действительно не знаю, что делать !! Может кто-нибудь, пожалуйста, помогите мне? Заранее спасибо!

Вот код для очистки и xyzstart () void clear ()

{

memset(buf,'\0',sizeof(buf));

memset(lno,'\0',sizeof(lno));

memset(def,'\0',sizeof(def));

memset(ref,'\0',sizeof(ref));

i=oldi=0;

memset(str,'\0',sizeof(str));

}

void xyzstart()

{

r=d=c=0;

for(;;c++,i++)

       {

           if(buf[i]==' ')

           break;

           if(buf[i]=='(') break;

           if(buf[i]==';')break;

           if(buf[i]=='\n') break;

           if(buf[i]=='=') break;

           if(buf[i]=='+' || buf[i]=='-') break;

           str[c]=buf[i];

        }

        str[c]='\0';

if(buf[i]=='=')

           assignment();

else if(buf[i]=='+' || buf[i]=='-') //Increments or decrements

            incdec();

          else if(buf[i]=='(')

                udefined();

}

Ответы [ 3 ]

3 голосов
/ 06 июня 2011

Я предполагаю, что одна из функций, вызываемых в while, уничтожает указатель файла (возможно, закрывает его).

Основные подозреваемые: clear и xyzstart.

2 голосов
/ 06 июня 2011

Некоторые заметки:

  1. Не используйте feof(fp) в качестве условия цикла while; функция вернет true только после того, как вы попробуете прочитать за концом файла, так что вы зацикливаетесь слишком часто. Проверьте результат вашей операции ввода (fgets вернет NULL при ошибке) и , затем тест на EOF, например:

    
    while(fgets(buf, sizeof buf, fp) != NULL)
      count++;
    if (feof(fp))
      printf("At end of file\n");
    
  2. НИКОГДА НИКОГДА НЕ НИКОГДА НИКОГДА НИКОГДА использовать gets: он будет вводить точку отказа в вашей программе (и, вероятно, имеет в этом случае). Начиная с C99 он устарел, и ожидается, что он выйдет из следующей версии языка (да, хаос, вызванный этим одним вызовом библиотеки, страшнее, чем перспектива взлома более чем 30-летнего устаревшего кода). Вместо этого используйте fgets или другую альтернативу.

Из кода, который вы разместили, я не вижу очевидных проблем; Я не знаю, почему feof дал бы дамп памяти, если предыдущий оператор был успешным rewind. Единственное, что я могу понять, это то, что указатель файла где-то перезаписывается (возможно, из-за переполнения буфера при вызове gets).

1 голос
/ 06 июня 2011
  1. что на самом деле "ясно" делает?
  2. этот цикл выглядит опасно:

    while (buf [i]! = '') // читать, пока не встретится пробел ..

что если buf не содержит пробелов?

...