<< 其他专栏文章

结构

结构模板和变量定义

1)无结构名

struct {
  …
} s1, s2;

一般适用于说明本地变量。

2)有结构名

struct date {
  …
} ;
struct date s1, s2;

通常用来说明外部结构变量,或需要在多个函数中用到的相同的结构的变量。

3)使用typedef

typedef struct {
  …
} DATE;

则变量定义为:DATE d, *pd, ad[10];
使用typedef定义结构类型名后,结构变量的定义(或说明)就更简洁了。

第二次作业

2.1 五子棋危险判断

【问题描述】

已知两人分别执白棋和黑棋在一个围棋棋盘上下五子棋,若同一颜色的棋子在同一条横行、纵行或斜线上连成5个棋子,则执该颜色棋子的人获胜。编写程序读入某一时刻下棋的状态,并判断是否有人即将获胜,即:同一颜色的棋子在同一条横行、纵列或斜线上连成4个棋子,且该4个棋子的两端至少有一端为空位置。
输入的棋盘大小是19×19,用数字0表示空位置(即没有棋子),用数字1表示该位置下了一白色棋子,用数字2表示该位置下了一黑色棋子。假设同一颜色的棋子在同一条横行、纵列或斜线上连成的棋子个数不会超过4个,并且最多有一人连成线的棋子个数为4。

【输入形式】

从控制台输入用来表示棋盘状态的数字0、1或2;每行输入19个数字,各数字之间以一个空格分隔,每行最后一个数字后没有空格;共输入19行表示棋盘状态的数字。

【输出形式】

若有人即将获胜,则先输出即将获胜人的棋子颜色(1表示白色棋子,2表示黑色棋子),然后输出英文冒号:,最后输出连成4个棋子连线的起始位置(棋盘横行自上往下、纵列自左往右从1开始计数,横行最小的棋子在棋盘上的横行数和纵列数作为连线的起始位置,若在同一行上,则纵列数最小的棋子位置作为起始位置,两数字之间以一个英文逗号,作为分隔符)。
若没有人获胜,则输出英文字符串:No。
无论输出什么结果,最后都要有回车换行符。

【输入样例1】

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 2 0 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 2 1 1 1 1 2 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 1 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 1 0 0 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

【输出样例1】

1:9,8

【输入样例2】

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 2 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

【输出样例2】

No

【样例说明】

在输入的样例1中,执白棋(数字1表示)的人即将获胜,连成4个棋子且有一端为空的起始位置在第9行第8列,所以输出1:9,8。
在输入的样例2中,还没有同一颜色的棋子连成4个,所以无人即将获胜,直接输出No。

「代码」
#include <stdio.h>
#include <string.h>


int main()
{
   int a[21][21];
   int i,j,pointi=-1,pointj=-1,point=0;
   
   //初始化数组,避免越界脏数据,四周均为-1
   for(i=0;i<21;i++)//第0列和第20列
   {
       a[i][0]=-1;
       a[i][20]=-1;
   }
   for(j=0;j<21;j++)//第0列和第20列
   {
       a[0][j]=-1;
       a[20][j]=-1;
   }
   
   
   for(i=1;i<20;i++)//读入数据
   for(j=1;j<20;j++)
   scanf("%d",&a[i][j]);
   
   
   for(i=1;i<20;i++)
   {
       for(j=1;j<20;j++)
       {
           
           //找白棋 1
           if(a[i][j]==1)
           {
               
               if( (a[i+1][j]==1 && a[i+2][j]==1 && a[i+3][j]==1 ) && (a[i+4][j]==0||a[i-1][j]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=1;
                   break;
               }//从当前0位置向下⬇️找,行++,列不变
               
               else if( (a[i][j+1]==1 && a[i][j+2]==1 && a[i][j+3]==1 ) && (a[i][j+4]==0||a[i][j-1]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=1;
                   break;
               } //当前0位置向右➡️找,行不变,列++
               
               else if( (a[i+1][j-1]==1 && a[i+2][j-2]==1 && a[i+3][j-3]==1 ) && (a[i+4][j-4]==0||a[i-1][j+1]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=1;
                   break;
               } //当前0位置向左下↙️找,行++,列--
               else if( (a[i+1][j+1]==1 && a[i+2][j+2]==1 && a[i+3][j+3]==1 ) && (a[i+4][j+4]==0||a[i-1][j-1]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=1;
                   break;
               } //当前0位置向右下↘️找,行++,列++
           }
           
           //找黑棋 2
           if(a[i][j]==2)
           {
               
               if( (a[i+1][j]==2 && a[i+2][j]==2 && a[i+3][j]==2 ) && (a[i+4][j]==0||a[i-1][j]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=2;
                   break;
               }//从当前0位置向下⬇️找,行++,列不变
               
               else if( (a[i][j+1]==2 && a[i][j+2]==2 && a[i][j+3]==2 ) && (a[i][j+4]==0||a[i][j-1]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=2;
                   break;
               } //当前0位置向右➡️找,行不变,列++
               
               else if( (a[i+1][j-1]==2 && a[i+2][j-2]==2 && a[i+3][j-3]==2 ) && (a[i+4][j-4]==0||a[i-1][j+1]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=2;
                   break;
               } //当前0位置向左下↙️找,行++,列--
               else if( (a[i+1][j+1]==2 && a[i+2][j+2]==2 && a[i+3][j+3]==2 ) && (a[i+4][j+4]==0||a[i-1][j-1]==0) )
               {
                   pointi=i;
                   pointj=j;
                   point=2;
                   break;
               } //当前0位置向右下↘️找,行++,列++
           }
           
       }
       if (point!=0)
       {
           printf("%d:%d,%d\n",point,pointi,pointj);
           break;
       }
   }
   
   if (point==0) printf("No\n");

   return 0;
}

2.2 字符串替换(新)

memset(str, 0, sizeof(str));//清空字符串str

【问题描述】

编写程序将一个指定文件中某一字符串替换为另一个字符串。要求:(1)被替换字符串若有多个,均要被替换;(2)指定的被替换字符串,大小写无关。

【输入形式】

给定文件名为filein.txt。从控制台输入两行字符串(不含空格,行末尾都有回车换行符),分别表示被替换的字符串和替换字符串。

【输出形式】

将替换后的结果输出到文件fileout.txt中。

【样例输入】

从控制台输入两行字符串:

in
out

文件filein.txt的内容为:

#include <stdio.h>
void main()
{
    FILE * IN;
    if((IN=fopen("in.txt","r"))==NULL)
    {
       printf("Can&rsquo;t open in.txt!");
       return;
    }
    fclose(IN);
}

【样例输出】

文件fileout.txt的内容应为:

#outclude <stdio.h>
void maout()
{
    FILE * out;
    if((out=fopen("out.txt","r"))==NULL)
    {
       prouttf("Can&rsquo;t open out.txt!");
       return;
    }
    fclose(out);
}

【样例说明】

输入的被替换字符串为in,替换字符串为out,即将文件filein.txt中的所有in字符串(包括iN、In、IN字符串)全部替换为out字符串,并输出保存到文件fileout.txt中。

「代码」
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLINE  1024
char *replace(char line[ ], char in[ ],char out[ ],char line1[ ]);
char line[MAXLINE],line1[MAXLINE];

int main( )
{
    char in[81], out[81];
    
    FILE *fi, *fp;
    
    scanf("%s", in);//被替换的字符串
    scanf("%s", out);//替换字符串
    
    
    
    if((fi = fopen("filein.txt", "r")) == NULL)
    {
        printf("Can't open file filein.txt !\n");
        return 404;
    }
    fp = fopen("fileout.txt", "w");
    
    while(fgets(line, MAXLINE-1, fi) != NULL)
    {
        
        replace(line, in, out, line1);
        fputs(line1, fp);
        puts(line1);
        
        memset(line1, 0, sizeof(line1));//清空line1
        
    }
    
    return 0;
}

char *replace(char line[ ], char in[ ],char out[ ],char line1[ ])
{
    int i, j, k, l;
    
    
    int len_in,len_out;
    len_in=strlen(in);//被替换的字符串长度
    len_out=strlen(out);//替换字符串长度
    
    for(i=0,l=0 ; line[i] != '\0'; i++,l++)
    {
        for(j=i,k=0;in[k]!='\0'&&tolower(line[j])==tolower(in[k]); j++,k++)
        ;
        if(in[k] == '\0')
        {
            strcat(line1, out);
            i=i+len_in-1;
            l=l+len_out-1;
            
        }
        else
            line1[l]=line[i];
            //i是字符串起始点
    }
    return line1;
}

2.3 加密文件

【问题描述】

有一种加密方法为:其使用一个字母串(可以含重复字母,字母个数不超过50)作为密钥。假定密钥单词串为feather,则先去掉密钥单词中的重复字母得到单词串feathr,然后再将字母表中的其它字母以反序追加到feathr的后面:

f e a t h r z y x w v u s q p o n m l k j i g d c b

加密字母的对应关系如下:

a b c d e f g h i j k l m n o p q r s t u v w x y z
f e a t h r z y x w v u s q p o n m l k j i g d c b

其中第一行为原始英文字母,第二行为对应加密字母。其它字符不进行加密。编写一个程序,用这种密码加密文件。假定要加密的文件名为encrypt.txt及加密后的文件名为output.txt,并假定输入文件中字母全为小写字母,并且输入密钥也全为小写字母。

【输入形式】

从标准输入中输入密钥串,并从文件encrypt.txt中读入要加密的内容。

【输出形式】

加密后结果输出到文件output.txt中。

【样例输入】

feather

和文件encrypt.txt中内容,例如被加密的文件encrypt.txt中内容为:

c language is wonderful.

【样例输出】

加密后output.txt文件中内容为:

a ufqzjfzh xl gpqthmrju.

【样例说明】

首先将给定的密钥单词去除重复字母,然后按照上面的加密对应表对encrypt.txt文件内容进行加密即可得到加密后的文件,其中只对英文字母进行加密对换,并且假设encrypt.txt中的英文字母全是小写字母。

「代码」
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLINE  1024

char keys[28];
int letters[28];

int main( )
{
    char key[28], c;
    int i,j;
    FILE *fi, *fp;
    
    scanf("%s", key);//密钥
    
    for( i=0,j=0; key[i] != '\0'; i++ )
    {
        //去掉密钥单词中的重复字母得到单词串
        if (letters[key[i]-'a']!=1)
        {
            keys[j]=key[i];
            letters[key[i]-'a']=1;//标记该字母已出现
            j++;
        }
    }
    for( i=25; i>=0 ; i-- )
    {
        //将字母表中的其它字母以反序追加到feathr的后面
        if (letters[i]!=1)
        {
            keys[j]='a'+i ;
            j++;
        }
    }
    
    if((fi = fopen("encrypt.txt", "r")) == NULL)
    {
        printf("Can't open file encrypt.txt !\n");
        return 404;
    }//文件打开失败报错
    fp = fopen("output.txt", "w");//输出文件
    
    c=fgetc(fi);
    while(c!=EOF)
    {
        
        if (isalpha(c))
        {
            fputc(keys[c-'a'], fp);
        }
        else fputc( c , fp);
        c=fgetc(fi);
    }
    
    return 0;
}

2.4 通讯录整理

【问题描述】

读取一组电话号码簿(由姓名和手机号码组成),将重复出现的项删除(姓名和电话号码都相同的项为重复项,只保留第一次出现的项),并对姓名相同手机号码不同的项进行如下整理:首次出现的项不作处理,第一次重复的姓名后面加英文下划线字符_和数字1,第二次重复的姓名后面加英文下划线字符_和数字2,依次类推。号码簿中姓名相同的项数最多不超过10个。最后对整理后的电话号码簿按照姓名进行从小到大排序,并输出排序后的电话号码簿。

【输入形式】

先从标准输入读取电话号码个数,然后分行输入姓名和电话号码,姓名由不超过20个英文小写字母组成,电话号码由11位数字字符组成,姓名和电话号码之间以一个空格分隔,输入的姓名和电话号码项不超过100个。

【输出形式】

按照姓名从小到大的顺序分行输出最终的排序结果,先输出姓名再输出电话号码,以一个空格分隔。

【样例输入】

15
liping 13512345678
zhaohong 13838929457
qiansan 13900223399
zhouhao 18578294857
anhai 13573948758
liping 13512345678
zhaohong 13588339922
liping 13833220099
boliang 15033778877
zhaohong 13838922222
tianyang 18987283746
sunnan 13599882764
zhaohong 13099228475
liushifeng 13874763899
caibiao 13923567890

【样例输出】

anhai 13573948758
boliang 15033778877
caibiao 13923567890
liping 13512345678
liping_1 13833220099
liushifeng 13874763899
qiansan 13900223399
sunnan 13599882764
tianyang 18987283746
zhaohong 13838929457
zhaohong_1 13588339922
zhaohong_2 13838922222
zhaohong_3 13099228475
zhouhao 18578294857

【样例说明】

输入了15个人名和电话号码。其中第一项和第六项完全相同,都是“liping 13512345678”,将第六项删除,第一项保留;

第八项和第一项人名相同,电话不同,则将第八项的人民整理为liping_1;同样,第二项、第七项、第十项、第十三项的人名都相同,将后面三项的人名分别整理为:zhaohong_1、zhaohong_2和zhaohong_3。

最后将整理后的电话簿按照姓名进行从小到大排序,分行输出排序结果。

「代码」
#include <stdio.h>
#include <string.h>

struct address_list {
    char name[30];
    long long int tel;
};

void sortbyName(struct address_list array[], int n);
void dealRepeat(struct address_list array[], int n);
void print(struct address_list array[], int n);

int main()
{
    
    struct address_list info[200];
    int i,n;
    
    scanf("%d",&n);//读取个数
    for(i=0;i<n;i++)
    scanf("%s %lld", info[i].name, &info[i].tel);//读取姓名和电话
    
    dealRepeat(info, n);//处理重复的项
    sortbyName(info, n);//按姓名排序
    print(info, n);

    return 0;
}

void dealRepeat(struct address_list array[], int n)
{
    int i, j;

    for(i=0; i<n; i++)
    {
        int count=0;
        for(j=i+1; j<n; j++)
        {
            if( strcmp(array[i].name, array[j].name)==0 )//姓名相等
            {
                if(array[i].tel == array[j].tel)//且电话相等,删除(赋值-1,输出时判断为删除项即可)
                {
                    strcpy(array[j].name, "-1");
                }
                else
                {
                    //对姓名相同手机号码不同的项,重复的姓名后面加英文下划线字符_和数字count
                    int len=0;
                    len=strlen(array[j].name);
                    array[j].name[len]='_';
                    array[j].name[len+1]='1'+count;
                    array[j].name[len+2]='\0';
                    count++;
                }
            }
        }
    }
}

void sortbyName(struct address_list array[], int n)
{
    int i, j;
    struct address_list tmp;
    for(i=0; i<n; i++)
    for(j=i; j<n; j++){
        if(strcmp(array[i].name,array[j].name)>0)
        {
            tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
        }
    }
}

void print(struct address_list array[], int n)
{
    int i;
    for(i=0;i<n;i++)
        if( strcmp(array[i].name,"-1")!=0 )//姓名为-1,判断为删除项
            printf("%s %lld\n", array[i].name, array[i].tel);
}

2.5 小型图书管理系统

【问题描述】

小明同学特别喜欢买书看书。由于书较多,摆放杂乱,找起来非常麻烦。这学期小明同学上了数据结构与程序设计课后,决定改变这种状况:用C开发一个小型图书管理系统。系统中包含的图书信息有:书名、作者、出版社、出版日期等。首先,图书管理系统对已有的书(原始书库,存放在一个文本文件中)按书名字典序进行(按书名中各字符的ASCII码值由小到大排序)摆放(即将原始无序的图书信息文件生成一个有序的文件,即新书库),以便查找。该管理系统可以对新书库中图书条目进行如下操作:
1.录入。新增书录入到书库中(即从输入中读入一条图书信息插入到已排序好的图按书文件相关位置处)
2.查找。按书名或书名中关键字信息在书库中查找相关图书信息,若有多本书,按字典序输出。
3.删除。输入书名或书名中关键字信息,从书库中查找到相关书并将其删除,并更新书库。

【输入形式】

原始的图书信息(原始书库)保存在当前目录下的books.txt中。
用户操作从控制台读入,首先输入操作功能序号(1代表录入操作,2代表查找操作,3代表删除操作,0代表将已更新的图书信息保存到书库中并退出程序),然后在下一行输入相应的操作信息(录入操作后要输入一条图书信息,查找和删除操作后只要输入书名或书名中部分信息)。程序执行过程中可以进行多次操作,直到退出(输入操作0)程序。
要求:
1、原始文件中的图书信息与录入的图书信息格式相同,每条图书信息都在一行上,包括书名(不超过50个字符)、作者(不超过20个字符)、出版社(不超过30个字符)和出版日期(不超过10个字符),只由英文字母和下划线组成,用一个空格分隔。图书信息总条数不会超过500.
2、下划线字符参加排序。
3、图书不会重名。

【输出形式】

进行录入和删除操作,系统会更新图书信息,但不会在控制台窗口显示任何信息。
进行查找操作后,将在控制台按书名字典序分行输出查找到的图书信息,书名占50个字符宽度,作者占20个字符宽度,出版社占30个字符宽度,出版日期占10个字符宽度,都靠左对齐输出。
最终按字典排序的图书信息保存在当前目录下的ordered.txt中,每条图书信息占一行,格式与查找输出的图书信息相同。

【样例输入】

假设books.txt中保存的原始图书信息为:
The_C_programming_language Kernighan Prentice_Hall 1988
Programming_in_C Yin_Bao_Lin China_Machine_Press 2013
Data_structures_and_Algorithm_Analysis_in_C Mark_Allen_Weiss Addison_Wesley 1997
ANSI_and_ISO_Standard_c Plauger Microsoft_Press 1992
Data_structures_and_program_design_in_C Robert_Kruse Pearson_Education 1997
Computer_network_architectures Anton_Meijer Computer_Science_Press 1983
C_programming_guidelines Thomas_Plum Prentice_Hall 1984
Data_structures_using_C Tenenbaum Prentice_Hall 1990
Operating_system_concepts Peterson Addison_Wesley 1983
Computer_networks_and_internets Douglas_E_Come Electronic_Industry 2017
用户控制台输入信息为:
1
Data_structures_and_C_programs Christopher Addison_Wesley 1988
2
structure
1
The_C_programming_tutor Leon_A_Wortman R_J_Brady 1984
2
rogram
3
rogramming
0

【样例输出】

用户输入“2 structure”后,控制台输出:

1.jpg

用户输入“2 rogram”后,控制台输出:

2.jpg

ordered.txt文件内容为:
3.jpg

【样例说明】

先读入books.txt中的10条图书信息,按照书名进行字典序排序;用户进行了五次操作,然后退出:第一次操作是插入了一条图书信息,这时有11条图书信息,按书名字典序排序为:
ANSI_and_ISO_Standard_c Plauger Microsoft_Press 1992
C_programming_guidelines Thomas_Plum Prentice_Hall 1984
Computer_network_architectures Anton_Meijer Computer_Science_Press 1983
Computer_networks_and_internets Douglas_E_Come Electronic_Industry 2017
Data_structures_and_Algorithm_Analysis_in_C Mark_Allen_Weiss Addison_Wesley 1997
Data_structures_and_C_programs Christopher Addison_Wesley 1988
Data_structures_and_program_design_in_C Robert_Kruse Pearson_Education 1997
Data_structures_using_C Tenenbaum Prentice_Hall 1990
Operating_system_concepts Peterson Addison_Wesley 1983
Programming_in_C Yin_Bao_Lin China_Machine_Press 2013
The_C_programming_language Kernighan Prentice_Hall 1988
第二次操作是查找书名包含structure的图书,有4本图书信息按照格式要求输出到屏幕;第三次操作又插入了一条图书信息,这时有12条图书信息;第四次操作查找书名包含rogram的图书,有6本图书信息按照格式要求输出到屏幕;第五次操作是删除书名包含rogramming的图书信息,有四条图书信息要删除,剩下八条图书信息;最后退出程序前将剩余的八条图书信息按照格式要求存储在ordered.txt文件中。

「代码」
#include <stdio.h>
#include <string.h>

struct library_list {
    char title[60];
    char author[30];
    char publisher[40];
    int  year;
    //title, author, publisher, year
};

void sortbyTitle(struct library_list array[], int n);//排序
void insert(struct library_list array[], int n);//录入
void search(struct library_list array[], int n, char t[]);//查找
void delete(struct library_list array[], int n, char t[ ]);//删除
void print(FILE *fp, struct library_list array[], int n);//输出
int index_(char s[ ], char t[ ]);

int main()
{
    FILE *in, *out;
    struct library_list info[600];
    int i = 0;
    
    if((in=fopen("books.txt","r")) == NULL){
        printf("Cann't Open file books.txt!\n");
        return 404;
    }
    if((out=fopen("ordered.txt","w")) == NULL){
        printf("Cann't Open file ordered.txt!\n");
        return 404;
    }
    
    while(fscanf(in, "%s %s %s %d", info[i].title, info[i].author ,info[i].publisher ,&info[i].year)!=EOF)
    {
        i++;
    }

    while(1)
    {
        int flag;
        scanf("%d",&flag);
        
        if(flag==1)//插入
        {
            scanf("%s %s %s %d", info[i].title, info[i].author ,info[i].publisher ,&info[i].year);
            i++;
        }
        else if (flag==2)//查找
        {
            char c[60];
            scanf("%s",c);
            sortbyTitle(info, i);//先排序
            search(info, i, c);
        }
        else if (flag==3)//删除
        {
            char c[60];
            scanf("%s",c);
            delete(info, i, c);
        }
        else if (flag==0)
        {
            sortbyTitle(info, i);
            print(out, info, i);
            break;
        }
    }
    
    fclose(in);
    fclose(out);
    
    return 0;
}

void sortbyTitle(struct library_list array[], int n)
{
    int i, j;
    struct library_list tmp;
    for(i=0; i<n; i++)
    for(j=i; j<n; j++){
        if(strcmp(array[i].title,array[j].title)>0)
        {
            tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
        }
    }
}

int index_(char s[ ], char t[ ])
{
    int i, j, k;
    for(i = 0; s[i] != '\0'; i++){
        for(j=i,k=0;t[k]!='\0'&&s[j]==t[k]; j++,k++)
        ;
        if(t[k] == '\0')
            return ( i);
    }
    return ( -1);
}

void search(struct library_list array[], int n, char t[ ])
{
    int i;
    for(i=0; i<n; i++)
    if(index_(array[i].title, t)>=0)
        printf("%-50s%-20s%-30s%-10d\n", array[i].title, array[i].author ,array[i].publisher ,array[i].year);
}

void delete(struct library_list array[], int n, char t[ ])
{
    int i;
    for(i=0; i<n; i++)
    if(index_(array[i].title, t)>=0)
        strcpy(array[i].title, "-1");
}

void print(FILE *fp, struct library_list array[], int n)
{
    int i;
    for(i=0;i<n;i++)
    if( strcmp(array[i].title,"-1")!=0 )//姓名为-1,判断为删除项
        fprintf(fp, "%-50s%-20s%-30s%-10d\n", array[i].title, array[i].author ,array[i].publisher ,array[i].year);
}
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐