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 ファイルの処理後にセグメンテーション エラーが発生します。

4

3 に答える 3

2

「最初から」少なくとも 1 つの理由:

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 バイトしかないため、メモリの上書きが発生します ('\0' ターミネータ用に 1 を予約してください):

char file[30];
...
strcpy(file,ent->d_name);
于 2013-03-22T19:07:52.293 に答える
1

XML 内には、説明していないように見える構造が 2 つあります。

  1. 属性のコンテンツにはエスケープされ>ていない文字が含まれている可能性があり、これによりカウントが失われる可能性があります。http://www.w3.org/TR/REC-xml/#NT-AttValueを参照してください。

  2. CDATA セクションには、終了文字列の一部として表示されない限り、文字<と文字の両方をリテラル テキストとして含めることができます。http://www.w3.org/TR/REC-xml/#NT-CharDataを参照してください。これにより、ロジックが大幅に狂ってしまう可能性があります。>]]>

ファイルを調べて、テキストが含まれているかどうかを確認してみませんCDATAか?

xsltproc または libxsltの使用を検討することをお勧めします。非常に単純な XSLT 変換を行うだけで、必要なものが正確に得られます。このような変換エンジンについては、XSLT を使用して XML ファイルの一部をプレーン テキストとして抽出するを参照してください。

于 2013-03-23T10:12:42.923 に答える
0

OK、別の問題のある場所:

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

d_name3 文字未満になる可能性があるため、メモリの上書きが再び発生する可能性があります。のような関数には注意しstrlen()、常にその結果を検証する必要があります。

于 2013-03-23T09:47:14.540 に答える