1. 程式人生 > >c語言唐詩300首查詢

c語言唐詩300首查詢

/*

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");


}