2013-03-22 2 views
0
#include<stdio.h> 
#include<stdlib.h> 
#include<dirent.h> 
#include<string.h> 

int main() 
{ 
    FILE *fin,*fout; 
    char dest[80]="/home/vivs/InexCorpusText/"; 
    char file[30]; 
    DIR *dir; 
    char c,state='1'; 
    int len; 
    struct dirent *ent; 
    if((dir=opendir("/home/vivs/InexCorpus"))!=NULL) 
    { 
    while((ent=readdir(dir))!=NULL) 
    { 
     if(strcmp(ent->d_name,".") && 
     strcmp(ent->d_name,"..") && 
     strcmp(ent->d_name,".directory")) 
     { 
     len=strlen(ent->d_name); 
     strcpy(file,ent->d_name); 
     file[len-3]=file[len-1]='t'; 
     file[len-2]='x'; 
     //strcat(source,ent->d_name); 
     strcat(dest,file); 
     printf("%s\t%s\n",ent->d_name,dest); 
     fin=fopen(ent->d_name,"r"); 
     fout=fopen(dest,"w"); 
     while((c=fgetc(fin))!=EOF) 
     { 
      if(c=='<') 
      { 
      fputc(' ',fout); 
      state='0'; 
      } 
      else if(c=='>') 
      state='1'; 
      else if(state=='1') 
      { 
      if(c!='\n') 
      fputc(c,fout); 
      if(c=='.') 
      { 
       c=fgetc(fin); 
       if(c==' '||c=='\n'||c=='<') 
       { 
       fputc('\n',fout); 
       ungetc(c,fin); 
       } 
       else fputc(c,fout); 
      } 
      } 
     } 
     } 
     close(fin); 
     close(fout); 
     strcpy(dest,"/home/vivs/InexCorpusText/"); 
    } 
    closedir(dir); 
    } 
    else 
    { 
    printf("Error in opening directory\n"); 
    } 
    return 0; 
} 

Я пытался конвертировать xml-файлы в текст. Этот код просто удаляет теги и ничего больше. Когда я выполняю этот код примерно для 300 файлов, он не показывает никаких ошибок, но когда число достигает 500 или более, я получаю ошибку сегментации после обработки около 300 файлов.Ошибка сегментации при преобразовании большого количества XML-файлов в текст

+1

Имеет ли ваша клавиатура '' ключ? – 2013-03-22 18:57:52

+1

Можете ли вы быть уверены, что имена файлов не превысят 29 символов? В противном случае вы можете переполнить 'файл'. Кроме того, вам нужно проверить, что 'fopen' не возвращает' NULL'. – jazzbassrob

+0

Вы пытались использовать отладчик, чтобы увидеть, где именно происходит ошибка? – Mike

ответ

2

По крайней мере одна из причин «с самого начала»:

Вот struct dirent заявление от человека:

On Linux, the dirent structure is defined as follows: 

     struct dirent { 
      ino_t   d_ino;  /* inode number */ 
      off_t   d_off;  /* offset to the next dirent */ 
      unsigned short d_reclen; /* length of this record */ 
      unsigned char d_type;  /* type of file; not supported 
              by all file system types */ 
      char   d_name[256]; /* filename */ 
     }; 

Вы в беде на любое имя больше, чем 30 (фактически 29) символов. перезапись памяти происходит потому, что файл имеет только 30 байт (резерв 1 для '\ 0' терминатор):

char file[30]; 
... 
strcpy(file,ent->d_name); 
+0

Спасибо за помощь Роман Никитченко. :). Но мое имя файла никогда не превышает более чем 23. – Vivs

0

ОК, еще проблемное место:

len=strlen(ent->d_name); 
.... 
file[len-3]=file[len-1]='t'; 
file[len-2]='x'; 

Поскольку d_name может иметь менее 3-х символов он снова может привести к перезаписи памяти. Вы должны быть осторожны с функциями, такими как strlen() и всегда подтверждать их результат.

+0

Но имя файла в формате xxxxxxx.xml. – Vivs

1

В XML есть две структуры, которые не отображаются в вашей учетной записи.

  1. Атрибут содержимое может содержать неэкранированные > символы, которые могли бы бросить свой счет. См. http://www.w3.org/TR/REC-xml/#NT-AttValue. Разделы

  2. CDATA может содержать как < и > символы как буквальный текст, до тех пор, пока они не появляются в части закрытия ]]> строки. См. http://www.w3.org/TR/REC-xml/#NT-CharData. Это может серьезно отбросить вашу логику.

Почему бы вам не посмотреть в файлах, чтобы увидеть, содержат ли они текст CDATA?

Возможно, вы захотите рассмотреть возможность использования xsltproc or libxslt; очень простое преобразование XSLT даст вам именно то, что вы хотите. См. Extract part of an XML file as plain text using XSLT для такого механизма преобразования.

+0

Это не вызовет никаких проблем в моем случае, так как после преобразования его в текст я изменяю его и вернусь к форме xml.BTW благодарит lavinio за такую ​​полезную информацию. :) – Vivs

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