将文本文件中的单词读入struct的问题
这是一个很长的程序的一部分,最基础的一部分,但是因为我对struct的掌握不熟练,所以卡住了。希望大家能够帮我看一下。
现在我有一个叫做text.txt的文本文件,内容是:
roses are red
violets are blue
i am schizophrenic
and so am i
希望有一段代码可以统计每个词有多少个,按字母顺序输出为:
am 2
and 1
are 2
blue 1
i 2
red 1
roses 1
schizophrenic 1
so 1
violets 1
希望实现的思路是用一个struct数组,每个struct元素有单词和出现次数两部分(必须用这个结构是因为以后这个东西还有其他用处。)因为初学C,没用过stuct,我就想,我先把文件里每一个词读入struct数组每一个元素的单词这部分搞定,算是一切的开始。没想到这一步就卡住了,程序编译了运行不出东西,所以希望大家能帮我看看。我知道这个可能花费不了高手多少时间,我对指针的概念也不是很熟悉,所以在struct读入解决后可能排序上也有困难,100分求一个能够按要求运行的程序。如果完成整段有困难的话,希望能和我在帖子里讨论帮我解决我的部分困惑。十分感谢!
[解决办法]
- C/C++ code
while(!feof(firstFile)) { fscanf(firstFile,"%s",temp.word); struct wordCounter counter[i]; strcpy(counter[i].word,temp.word); counter[i].count = 1; printf("%s\n",counter[i].word); i++; }
[解决办法]
- C/C++ code
#include <stdio.h>#include <string.h>#define MAX_LENGTH 40#define MAX_WORD 50void ReadText(FILE *firstFile);void insertList(char *);void output();struct wordCounter { char word[MAX_LENGTH]; unsigned int count;};struct wordCounter counter[MAX_WORD];int counterSize=0;int main(void){ // Declaration FILE *text; //FILE *remove; //Body text = fopen("E:\\c++\\ListViewTest01\\C语言试验用项目\\C语言试验用项目\\text.txt", "r"); // 文件目录需要自己调整 ReadText(text); output(); // End fclose(text);}void ReadText(FILE *firstFile){ char str[40]; while(!feof(firstFile)) { fscanf(firstFile,"%s",str); insertList(str); }}void insertList(char *word) // 此函数将读入的word插入数组中,若数组中已有该word,则增量计数{ int i,j,flag=1,cmp; for (i=0;i<counterSize;++i) { cmp=strcmp(counter[i].word,word); // 比较数组中与当前字符串 if (cmp==0) // 若想等则增量计数 { counter[i].count++; flag=0; break; } if (cmp>0) // 若已大于当前字符串,需要插入word到此位置 { for (j=counterSize;j>=i;--j) // 先移开后面的元素 counter[j+1]=counter[j]; strcpy(counter[i].word,word); // 再插入当前word counter[i].count=1; // 置计数为1 ++counterSize; // 累加word总数 flag=0; // 复位标志 break; } } if (flag) // 若未找到同样word且未发生插入操作,则将word插到尾部 { strcpy(counter[counterSize].word,word); counter[counterSize++].count=1; }}void output(){ int i; for (i=0;i<counterSize;++i) printf("%s %d\n",counter[i].word,counter[i].count);}
[解决办法]
这个问题应该用哈希表啊,不过那是Perl语言里的,希望对你能有帮助。
[解决办法]
赞一下5楼吧,5楼的处理方法是每次读1行,如何处理其中的单词,放到struct数组中。
你自己的问题还是很多,对比一下吧。
[解决办法]
看看下面这个代码,我感觉非常好:
- C/C++ code
#include<stdlib.h>#include<stdio.h>#include<string.h>#define NHASH 29989//比总数 大一些的 质数,这个例子单词的总数为 299131#define MULT 31 // 单个单词可以选择的数目大一些的质数。 这个例子为英语字母26typedef struct node *nodeptr;typedef struct node{ char *word; int count; nodeptr next;}hashnode;nodeptr bin[NHASH];unsigned int hash(const char *p){ unsigned int h=0; for(;*p;++p) { h=MULT*h+*p; } return h%NHASH;}void incword(const char * buf){ unsigned int h=hash(buf); nodeptr p; for(p=bin[h];p!=NULL;p=p->next) { if(strcmp(buf,p->word)==0 ) ++(p->count); return ; } p=(nodeptr)malloc(sizeof(hashnode)); p->word=(char *)malloc(strlen(buf)+1); p->count=1; strcpy(p->word,buf); p->next=bin[h]; bin[h]=p;}int main(void){ int i=0,sum=0; char buf[128]; nodeptr p; freopen("deep_cpp.txt","r",stdin); for(i=0;i<NHASH;++i) { bin[i]=NULL; } while(scanf("%s",buf)!=EOF) { incword(buf); ++sum; } for(i=0;i<NHASH;++i) { for(p=bin[i];p!=NULL;p=p->next) { printf("%s\t%d\n",p->word,p->count); } } printf("total %d words\n",sum); return 0;}
[解决办法]
[code=C/C++][/code]
/******************************************************************************/
/* Function : finish the tree to search */
/* Time : 29/04/12 19:37 */
/******************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
struct treeNode
{
char *word; //the pointer to a tree
int count; //the times of a word
struct treeNode *left; //left node of the tree
struct treeNode *right; //right node of the tree
};
#define MAXWORD 500
#define BUFSIZE 500
char buf[BUFSIZE]; //the buffer to ungetch
int bufp = 0; //the next free seat of buf
int getch(void);
void ungetch(int c);
char *strdup(char *s);
struct treeNode *treeAlloc(void);
int getword(char *word,int lim);
struct treeNode *addtree(struct treeNode *p,char *w);
void treeprint(struct treeNode *p);
int main()
{
struct treeNode *root;
char word[MAXWORD];
root = NULL;
while(getword(word,MAXWORD) != EOF)
if(isalpha(word[0]))
root = addtree(root,word);
treeprint(root);
system("pause");
return 0;
}
/*
** add a node
*/
struct treeNode *addtree(struct treeNode *p,char *w)
{
int cond;
if(p == NULL)
{
p = treeAlloc();
p->word = strdup(w);
p->count = 1;
p->left = p->right = NULL;
}
else if((cond = strcmp(w,p->word)) == 0)
{
p->count++;
}
else if(cond < 0)
{
p->left = addtree(p->left,w);
}
else
{
p->right = addtree(p->right,w);
}
return p;
}
/*
** print the tree from it's left to it's right
*/
void treeprint(struct treeNode *p)
{
if(p != NULL)
{
treeprint(p->left);
printf("%4d %s\n",p->count,p->word);
treeprint(p->right);
}
}
/*
** creat a treeNode
*/
struct treeNode *treeAlloc(void)
{
return (struct treeNode *)malloc(sizeof(struct treeNode));
}
/*
** copy the s
*/
char *strdup(char *s)
{
char *p;
p = (char *)malloc(sizeof(char));
if(p != NULL)
{
strcpy(p,s);
}
return p;
}
/*
** get a word or character from the stdin
*/
int getword(char *word,int lim)
{
int c;
char *w = word;
while(isspace(c = getch()))
;
if(c != EOF)
*w++ = c;
if(!isalpha(c))
{
*w = '\0';
return c;
}
for(;--lim > 0;w++)
{
if(!isalnum(*w = getch()))
{
ungetch(*w);
break;
}
}
*w = '\0';
return word[0];
}
int getch(void)
{
return (bufp > 0)?buf[--bufp] : getchar();
}
void ungetch(int c)
{
if(bufp >= BUFSIZE)
{
printf("ungetch: too many characters\n");
}
else
{
buf[bufp++] = c;
}
}
这是依靠二叉树实现的,看着代码挺多的,其实运行是很有效率的。
[解决办法]
将文本文件中的单词读入struct的问题
这种思路,跟以前写彩票软件差不多。
比如txt文件里有开奖号码:
期数 开奖号码 和值
第 2012003 期 386 17
如何读取 文件里的数字"0"-"9" 方法差不多。
你可以参考下,我的彩票软件 源代码:
http://blog.163.com/wenxianliang08@126/blog/static/8358326320114168830219/
[解决办法]
用刚学的链表写了个,问题能解决,只是读数据的时候有点问ti...见谅
- C/C++ code
#include<stdio.h>#include<string.h>#include<stdlib.h>struct str{ char s[21]; int n; struct str *next;};struct str *head=NULL,*now=NULL,*N=NULL;int flag_fist=1;int process(char*);int main(){ FILE *f; char string[21]; f=fopen("K:\\Workspase\\test\\test.txt","r"); while(!feof(f)){ if(flag_fist){ head=malloc(sizeof(struct str)); now=head,N=head; }else N=malloc(sizeof(struct str)); N->next=NULL; fscanf(f,"%s",string); if(!process(string)){ strcpy(N->s,string); N->n=1; } if(!flag_fist){ now->next=N; now=N; }else flag_fist--; } for(;head;head=head->next){ printf("%s %d\n",head->s,head->n); } fclose(f); return 0;}int process(char *s){ struct str *i=head; for(;i&&strcmp(s,i->s);i=i->next); if(!i) return 0; i->n++; return 1;}
[解决办法]
在不考虑性能之类的前题下,其实这个用链表来实现,挺简单的。
你可以把链表看成是一个动态数组。
昨天我发了一个标题叫:“c版的ArrayList...” ,今天早上我对昨天写好的arraylist稍做修改,写了一个统计每个词有多少个,按字母顺序输出的小程序,你也可以下载看一下。
下载地址:
http://download.csdn.net/detail/test_lockxxx/4266808
[解决办法]
这个程序 要分成 好几个步骤呢。、
楼主现在基础都不牢固,这个程序对你来说有点难。
具体步骤参考。
1.打开文件、fopen
2,读取每一行 fgets
3.把每一行的字符串分割开来。strtok。
4.把所有的字符串存入一个数组。
5.遍历数组,查看所有字符串的数量。、
6.把字符串和数量放入结构体。、
各个函数,我已经给出。具体程序要靠自己努力。、
别人给你写出来,对自己没有好处。不如自己慢慢写。、
[解决办法]
将程序调试了一下...现在应该完全能符合了...希望对你有帮助
- C/C++ code
#include<stdio.h>#include<string.h>#include<stdlib.h>struct str{ char s[21]; int n; struct str *next;};struct str *head=NULL,*N=NULL;int flag_fist=1;int process(char*);int main(){ FILE *f; char string[21]; struct str *i,*l; f=fopen("K:\\Workspase\\test\\test.txt","r"); while(1){ if(flag_fist){ head=malloc(sizeof(struct str)); //不检查是否分配到空间 N=head; }else N=malloc(sizeof(struct str)); //同上 N->next=NULL; fscanf(f,"%s",string); if(feof(f)) break; //注意!!用这里控制循环,防止最后一个字符串被读多一次 if(!process(string)){ //如果字符串第一次出现就加入链表,否则只计数 strcpy(N->s,string); N->n=1; if(!flag_fist){ for(i=head;i&&*N->s>*i->s;l=i,i=i->next); //用插入的方法进行排序(根据首字母大小) if(!i) l->next=N; //将节点放在尾 if(i==head) head=N,head->next=i; //将节点放在首 else l->next=N,N->next=i; //在中间的位置插入 }else flag_fist--; } } for(;head;head=head->next){ printf("%s %d\n",head->s,head->n); } fclose(f); return 0;}int process(char *s){ struct str *i=head; for(;i&&strcmp(s,i->s);i=i->next); if(!i) return 0; //该字符串没出现过 i->n++; //该字符串已经出现过 return 1;}