c語言唐詩300首查詢
阿新 • • 發佈:2018-12-27
/*
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");
}
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");
}