#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个文件后收到分段错误。
答案 0 :(得分: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)字符的名字上遇到麻烦。发生内存覆盖是因为 file 只有30个字节('\ 0'终结符保留1):
char file[30];
...
strcpy(file,ent->d_name);
答案 1 :(得分:1)
XML中有两种结构,它们不会出现在您的帐户中。
属性内容可以包含未转义的>
个字符,这些字符可能会丢失您的计数。请参阅http://www.w3.org/TR/REC-xml/#NT-AttValue。
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。
答案 2 :(得分:0)
好的,另一个有问题的地方:
len=strlen(ent->d_name);
....
file[len-3]=file[len-1]='t';
file[len-2]='x';
因为d_name
可能少于3个字符,所以它可能再次导致内存覆盖。
您应该对strlen()
之类的函数小心,并始终验证其结果。