统计文件中英文单词数目并输出到文本文件中,这个程序中的1.txt比较小时可以运行,比较大时输出文件就不能打开,求解答

qq_42307848 2018-05-25 10:56:05
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MaxWord 32
#define N 10000

struct Word_Item
{
char word[MaxWord+1]; // 单词
int freq; // 词频
struct Word_Item * next; // 指针
};
typedef struct Word_Item WordItem;
WordItem list[N];

int count=0;

int hash(char word[ ]) // 计算单词的哈希值(散列值)
{
int ch, hash;
while ( ch = *word++ )
hash = hash * 131 + ch;
return hash;
}

WordItem * findCreateNode(WordItem *head, char w[ ])
{
WordItem * p = head->next;
while ( 1 ) { //判断w中的单词是否已经出现
if( strcmp(head->word, w)==0 )
return head;
if( head->next )
head = head->next;
else break;
}
p = (WordItem*)malloc(sizeof(WordItem));
strcpy(p->word, w);
p->freq = 0;
p->next = NULL;
head->next = p;
return p;
}

WordItem * findWord(char w[ ])
{
int h = hash(w) % N;
if(h<0) h=-h;
if(list[h].word [0] == '\0' ) {
strcpy(list[h].word, w);
return list + h;
}
return findCreateNode(list+h, w);
}

void add_word(WordItem * head, char a[]){ //添加单词和统计个数
sprintf(head->word,"%s",a);
head->freq++;
count++;
}

int IsLetter(char *p){
int flag=0;
char *t;
for(t=p;*t!='\0';t++)
if(*t>='a'&&*t<='z'||*t>='A'&&*t<='Z'|| *t=='’' || *t=='‘'
|| *t==',' || *t=='.' || *t=='!' || *t=='?' || *t=='"')
continue;
if(*t=='\0')
flag=1;

return flag;
}

char ToLower(char *p){
char *i;
for(i=p;*i;i++){
if(*i<='Z'&&*i>='A')
*i=*i-'A'+'a';
}
return *p;
}

void display(FILE * fp){ //统计单词和出现次数输出到屏幕和文件中
WordItem * ptr;
int i, k=1;
for(i=0;i<N;i++){
if(list[i].word[0]!='\0'){
printf("%5d %12s %5d\n", k, list[i].word ,list[i].freq);
fprintf(fp,"%5d %12s %5d\n",k, list[i].word ,list[i].freq);
k++; }
for(ptr=list[i].next ;ptr!=NULL;ptr=ptr->next,k++){
printf("%5d %12s %5d\n", k, ptr->word,ptr->freq);
fprintf(fp,"%5d %12s %5d\n", k, ptr->word,ptr->freq);
}
}
printf("The number of the txt is %d\n",count);
fprintf(fp,"The number of the txt is %d\n",count);
for(i=0;i<N;i++)
for(ptr=list[i].next ;ptr!=NULL; ptr=ptr->next){
free(ptr);
}
}

int main(void)
{
FILE *fp1,*fp2;
WordItem *ptr;

fp1 = fopen("2.txt","r"); //打开文件“1.txt”
if (!fp1)
return -1;

char buf[512], w[20], *p, *s;
while( fscanf( fp1, "%s", buf ) > 0 ) // 从文件中读取一个字符串
{
for( p = buf; *p; )
{
while( *p && ! IsLetter(p) )
p ++; // 过滤非字母
for( s = w; s < &w[sizeof(w)] && IsLetter(p) ; s++, p++ )
*s = ToLower(p); // 转换为小写,保存到单词中
*s = '\0'; // 字符串结束符
ptr=findWord (w); //储存w中的单词
add_word(ptr,w);
if((fp2 = fopen("3.txt","w"))==NULL){ //追加初始化
printf("can not open file");
exit(0);
}
}
}
display(fp2);
fclose(fp1);
fclose(fp2);
}
...全文
989 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_42307848 2018-05-25
  • 打赏
  • 举报
回复
修改之后输出过程中还是会出错,自动终止。希望能更加详细的解答一下
自信男孩 2018-05-25
  • 打赏
  • 举报
回复
while(fscanf( fp1, "%s", buf ) > 0 )
这个操作是从文件中读取一串字符,但是文件里没有'\0'。建议使用fgets。
宁南学者 2018-05-25
  • 打赏
  • 举报
回复
在循环中反复打开文件,因为文件描述符有限,导致用尽后,会打开文件失败。 另外 打开的每一个文件描述符,用户需要关闭,不然资源泄露给。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧