读书人

将文本文件中的单词读入struct的有关问

发布时间: 2012-05-03 14:06:56 作者: rapoo

将文本文件中的单词读入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;} 

读书人网 >C语言

热点推荐