C语言学习-15_qsort_bsearch函数

一、函数介绍

(1)qsort

名称描述
函数作用对数组进行排序。
函数定义void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
参数介绍base:需要排序的数组。nmemb:数组中的元素个数。size:单个元素的大小。compar:比较函数名。
特别说明int (*compar)(const void *, const void *)比较函数中的两个参数,都为数组元素,样例具体可以参考以下的例子函数:CompareTotalValueDesc。

(2)bsearch

名称描述
函数作用排序数组中根据关键字查找匹配的数据。
函数定义void *bsearch(const void *key, const void *base,size_t nmemb, size_t size,int (*compar)(const void *, const void *));
参数介绍key:需要查找的关键词。base:需要查找的数组。nmemb:数组中的元素个数。size:单个元素的大小。compar:比较函数名。
特别说明int CompareBSearch(const void *key, const void *pelem)(1)bsearch的比较函数和qsort不同,第一参数为需要查找的关键词的指针。(2)由于bsearch用的是二分查找法实现的,所以查找的数组必须是有序的,建议和qsort成对出现。

二、实现内容

(1)读取文本文件中的数据存放到数组中。
(2)对数组按照一定规律进行排序。
(3)在排好序的数组中,根据关键字查找某一行的数据。

三、测试数据(test.txt)

lxg 100 100 100
zxj 98 99 98
czg 99 99 99
test 99 66 88
xue 88 33 99
haha 1 1 1
xxx 3 78 00
jiu 98 32 11

四、虚机练习源码

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

#define NameSize 6
//结构体中Name的长度
#define StructSize 4
//结构体中元素的个数
#define FileDataNums 8
//读取文件中数据的行数,由于需要放到数组中

struct stu
{
    char Name[NameSize];
    int Math;
    int Chinese;
    int English;
};

void main()
{
    void ReadFileData(char* filename, struct stu *array);
    void SelectArray(struct stu *array);
    int CompareTotalValueDesc(const void *p1, const void *p2);
    int CompareTotalValueAsc(const void *p1, const void *p2);
    int CompareBSearch(const void *key, const void *pelem);
    void PrintOtherString();

    char filename[30] = "//opt//test.txt";
    struct stu array[FileDataNums];
    struct stu *res;
    int key = 98;

    ReadFileData(filename,array);
    printf("original array:\n");
    SelectArray(array);
    qsort(array, FileDataNums, sizeof(struct stu), CompareTotalValueAsc);
    printf("math asc array:\n");
    SelectArray(array);
    qsort(array, FileDataNums, sizeof(struct stu), CompareTotalValueDesc);
    printf("math desc array:\n");
    SelectArray(array);
    res = bsearch(&key, array, FileDataNums, sizeof(struct stu), CompareBSearch);
    printf("Bsearch Math : %d , Name : %s , Math : %d\n",key,res->Name,res->Math);
}

int CompareBSearch(const void *key, const void *pelem)
{
   int *p1 = (int *)key;
   struct stu *ps1 = (struct stu*)pelem;
   int num1 = *p1;
   int num2 = ps1->Math; 
   //printf("num1 : %d, num2 : %d\n",num1,num2);
   return num2 - num1;
}

int CompareTotalValueDesc(const void *p1, const void *p2)
{
   struct stu *ps1 = (struct stu*)p1;
   struct stu *ps2 = (struct stu*)p2;

   return (ps2->Math) - (ps1->Math);
}

int CompareTotalValueAsc(const void *p1, const void *p2)
{
   struct stu *ps1 = (struct stu*)p1;
   struct stu *ps2 = (struct stu*)p2;
   
   return (ps1->Math) - (ps2->Math);
}

//只能读取空格分隔,其他符号分隔再学习
void ReadFileData(char* filename, struct stu *array)
{
    FILE *fp;
    char NameTmp[NameSize];
    int MathTmp;
    int ChineseTmp;
    int EnglishTmp;
    int flag;
    char FormatString[12];
    char PrintString[14];
    int filenums = 0;
  
    strcpy(FormatString,"%s %d %d %d");
    strcpy(PrintString,"%s %d %d %d\n");

    fp = fopen(filename,"r");
    if(fp == NULL)
    {
        printf("%s no exsits!!!\n",filename);
        exit(0);
    }

    while(!feof(fp))
    {
        flag = fscanf(fp,FormatString,NameTmp,&MathTmp,&ChineseTmp,&EnglishTmp);
        if(flag!=StructSize) //防止重复读取最后一行
        {
            break;
        }
        strcpy((&array[filenums])->Name,NameTmp);
        (&array[filenums])->Math = MathTmp;
        (&array[filenums])->Chinese = ChineseTmp;
        (&array[filenums])->English = EnglishTmp;
        filenums++;
        //printf(PrintString,NameTmp,MathTmp,ChineseTmp,EnglishTmp);
    }
    printf("filenums : %d\n",filenums); 
    fclose(fp);
}

void SelectArray(struct stu *array)
{
    void PrintOtherString();
    int i;
    
    PrintOtherString();
    printf("Name  Math  Chinese  English\n");
    for(i=0;i<FileDataNums;i++)
    {
        printf("%-4s  %-4d  %-4d     %-4d\n",
                               (&array[i])->Name,
                               (&array[i])->Math,
                               (&array[i])->Chinese,
                               (&array[i])->English);
    }
    PrintOtherString();
}

void PrintOtherString()
{
    printf("===================\n");
}

五、虚机运行结果


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值