c语言唐诗300首查询

来源:互联网 发布:php json 中文乱码 编辑:程序博客网 时间:2024/05/01 12:56
/*

1、将所有的诗词都从文件中解析出来存入结构体数组poems[320]
2、调用searchPoem(),进行查询并显示查询结果
3、countPoems():利用链表对经过排序的作者指针数组进行统计并进行输出
注意:个别标题、作者字符比较多,所用空间要足够大
      文件中没有第175首诗,所以其实只有319首,现已添加
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>  //malloc


struct Poem{
    char title[256]; //第208首诗的标题很长
    char author[10];
    char content[512];
};
typedef struct Poem Poem;


struct AuthorInfo{
    char name[10];
    int poemNum;
    struct AuthorInfo *next;
};


typedef struct AuthorInfo AuthorInfo;


Poem poems[320];
void initPoems();
void showPoems();
void searchPoem(char *keywords,int type);
void countPoems();


int main(){
    initPoems();


    while(1){
        printf("|--------------------------------|\n");
        printf("| 1. 作者查询 | 2. 标题查询      |\n");
        printf("|--------------------------------|\n");
        printf("| 3. 内容查询 | 4. 统计作者信息  |\n");
        printf("|--------------------------------|\n");


        printf("请输入选项: ");
        int choice=0;
        scanf("%d",&choice);


        switch(choice){
        case 1:
        case 2:
        case 3:
            printf("请输入查询关键字:");
            char keywords[20];
            scanf("%s",keywords);
            searchPoem(keywords,choice);
            break;
        case 4:
            //作者信息统计模块调用
            countPoems();
            break;
        case 88:
            return 0;
            break;
        default:
            break;
        }


    }




    return 0;
}


//初始化,多文件并且将全部诗都存放于结构体数组poems中
void initPoems(){
    const int SIZE = 256;
    FILE *fp;


    if((fp=fopen("ts300.txt","r"))==NULL){
        printf("error......");
        return;
    }
    int i=0;
    char curr[SIZE];
    while(!feof(fp)){
        fgets(curr,SIZE,fp);


        // 判断当前内容是否为诗词标题
        if(curr[0]>='0' && curr[0]<='3'){
            //printf("%c\n",curr[0]);
            //printf("%s",curr+3);
/*
    //利用strtok将原标题中的作者和诗词题目分离,不过有可能产生乱码
            char *temp = NULL;
            temp = strtok(curr+3,":");


            strcpy(poems[i].author, temp);
            //printf("temp:%s\n",temp);


            temp = strtok(NULL,":");
            strcpy(poems[i].title, temp);
            //printf("temp:%s\n",temp);
*/
            /*
             * 通过指针的操作获取作者和诗词题目,可以尽可能的避免乱码
             */


            //获取冒号在原字串中的指针
            char* flagPos = strstr(curr,":");
            //将标题行中全部内容(编号除外)复制到author中,此时标题也被复制了
            strcpy(poems[i].author,curr+3);


            //将作者名字后面第一个字符设置为字符串终结标记,这样author中就只有作者姓名了
            poems[i].author[flagPos-curr-3] = '\0';


            //将标题复制到title中
            strcpy(poems[i].title,flagPos+2);


            //printf("%s \t %s\n",poems[i].author,poems[i].title);


            fgets(curr,SIZE,fp);//读取标题行下面的空行
            strcpy(poems[i].content,"");//初始化情况content
            do{
                fgets(curr,SIZE,fp);
                strcat(poems[i].content,curr);
                //printf("i=%d\n",i);
                //printf("=%s=\n",curr);
            }while(curr[0]!=10);


            i++;
        }
        //printf("%s",curr);
    }


    fclose(fp);
    //showPoems();


}
/*调试用,显示所有的分析结果*/
void showPoems(){


    int i;
    for(i=0;i<320;i++){
        printf("%s : %s",poems[i].author,poems[i].title);
        printf("%s\n",poems[i].content);
    }
}


void searchPoem(char *keywords,int type){
    if(type<1 || type>3){
        printf("查询类型参数错误!");
        return;
    }


    int i;
    char *temp=NULL;
    for(i=0;i<320;i++){
        switch(type){
            case 1:
                temp = strstr(poems[i].author,keywords);
                break;
            case 2:
                temp = strstr(poems[i].title,keywords);
                break;
            case 3:
                temp = strstr(poems[i].content,keywords);
                break;
        }


        if(temp!=NULL){
            printf("%s:%s\n%s",poems[i].author,poems[i].title,poems[i].content);
        }
//需要实现分屏显示
    }
}


void countPoems(){
    Poem *p[320];
    int i,j;
    for(i=0;i<320;i++){
        p[i] = &poems[i];
    }


    //利用冒泡对指向poems个元素的指针数组以姓名进行升序排序
    Poem *t=NULL;
    for(i=0;i<320-1;i++){
        for(j=i+1;j<320;j++){
            if(strcmp(p[i]->author,p[j]->author)>0){
                t = p[i];
                p[i] = p[j];
                p[j] = t;
            }
        }
    }


/*
    for(i=0;i<320;i++){
        printf("%s %s",p[i]->author,p[i]->title);
    }
*/
    //定义链表第一个节点
    AuthorInfo *head;
    head = (AuthorInfo *)malloc(sizeof(AuthorInfo));
    //初始化第一个节点
    strcpy(head->name,p[0]->author);
    head->poemNum=1;
    head->next=NULL;


    //依次创建新的节点并且加入到链表的尾部
    AuthorInfo *preNode =head;
    for(i=1;i<320;i++){
        if(strcmp(p[i]->author,preNode->name) == 0){
            preNode->poemNum++;
        }else{
            AuthorInfo *newNode=malloc(sizeof(AuthorInfo));
            //printf("%d  %s  %d\n",strlen(p[i]->author),p[i]->author,strlen(newNode->name));


            strcpy(newNode->name,p[i]->author);
            newNode->poemNum=1;
            newNode->next=NULL;
            preNode->next = newNode;
            preNode = newNode;
        }
    }


    //将统计结果进行输出:从链表的头开始以此向后进行访问
    AuthorInfo *node = head;
    while(node->next!=NULL){
        printf("+-----------------+\n");
        printf("|%-10s|%6d|\n",node->name,node->poemNum);
        node = node->next;
    }
    printf("+-----------------+\n");
    printf("|%-10s|%6d|\n",node->name,node->poemNum);
    printf("+-----------------+\n\n\n");


}
原创粉丝点击