c语言3月23日学习总结

1.数据块读写函数fread和write

/*

     fwrite 和 fread 是数据的写入和读取的函数

     每次读写一块数据,不是读取字符个数


     fwrite 写入数据到文件中

     1) 字符串

        FILE *fp = fopen("fwriteString.txt","w");

        if(fp!=NULL){

           // fwrite(buffer,size,count,fp);
           char str[]="helloWorld!";
           fwrite(str,strlen(str),1,fp);
           printf("文件写入成功!\n");

        }

        fcolose(fp);
         fp = NULL;


 */


#include 
#include 
/**
 *  fwrite写入一个字符串到文件中
 */

void test1(){

    //定义文件指针
    FILE *fp = fopen("fwriteString.txt","w");

    //判断文件是否打开成功
    if(fp!=NULL){

        // fwrite(buffer,size,count,fp);
        char str[]="helloWorld!";
        //使用fwrite 写入一块数据
        fwrite(str,strlen(str),1,fp);
        printf("文件写入成功!\n");

    }

    fclose(fp);

    fp = NULL;

}


//用fwrite 写入一个二进制文件
void test2(){

    //定义文件指针
    FILE *fp = fopen("d.data","wb");   //w写入   b 二进制

    //判断文件是否打开成功
    if(fp!=NULL){

        int num = 10;
        //写入到文件中
        fwrite(&num, sizeof(num), 1, fp);

        printf("写入文件成功!\n");

    }

    fclose(fp);

    fp = NULL;

}

/**
 *  从文件中读取二进制数据
 */
void test3(){

    //定义文件指针
    FILE *fp = fopen("d.data","rb");   //w写入   b 二进制

    //判断文件是否打开成功
    if(fp!=NULL){

        int num = 0;
        //fread(buffer,size,count,fp);
        fread(&num, sizeof(num), 1, fp);
        printf("读取成功:num = %d\n",num);

    }

    fclose(fp);

    fp = NULL;

}

int main(int argc, const char * argv[]) {

    test3();

    return 0;
}

2.应用:从文件中读取结构体信息


#include 

int main(int argc, const char * argv[]) {

    //1、定义结构
   struct Student {
    char name[20];
    char sex;
    int age;
    float score;
   };
    //2、定义结构数组
    //3、接收用户输入的内容
    struct Student stu[5]={{"zbz",'F',38,59.99f},{"sb",'F',48,59.99f},{"cgx",'F',18,59.99f},{"dlj",'M',8,59.99f},{"banzhang",'Y',18,99.99f}};

    //4、写入数据
    FILE *fp = fopen("student.data", "wb+");

    if (fp!=NULL) {

         //       fwrite(&stu[i],sizeof(struct Studnet),1,fp)
        for (int i=0; i<5; i++) {
            //
            fwrite(&stu[i],sizeof(struct Student),1,fp);
        }

        printf("文件写入成功!\n\n\n");
    //      立即读取

    //      文件指针拉回来
        rewind(fp);

    //      定义结构数组,接收从文件中读取的数据
        struct Student stuArray[5];
        printf("姓名\t\t性别\t\t年龄\t\t成绩\n");
        for (int i=0; i<5; i++) {
            //读取数据并且保存到 stuArray中
            fread(&stuArray[i],sizeof(struct Student),1,fp);

            printf("%s\t\t%c\t\t%d\t\t%.2f\n",stuArray[i].name,stuArray[i].sex,stuArray[i].age,stuArray[i].score);
        }


    //      遍历显示
    }

    return 0;
}

3.格式化读写函数fscanf和fprintf

/*
    fscanf()   格式化的读取,从文件中读取


    fprintf() 格式化的写入,写入到文件中

       10:9.9,xxxx,1.jpg#

    fprintf(fp,"%d:%.2f,%s,%s#",10,9.9f,"最便宜的面膜","20150301010101.jpg");


 */


#include 
/**
 *  格式化的写入
 */
void test1(){

    FILE* fp = fopen("fprintf.txt", "w");
    if (fp!=NULL) {

        //格式化写入
        int productId = 10;
        float productPrice = 9.9f;
        char *productTitle = "最便宜的面膜";
        char *productTitleImg="20150301010101.jpg";

        fprintf(fp,"%d:%.2f,%s\n%s",productId,productPrice,productTitle,productTitleImg);

        printf("数据写入成功!\n");

    }

    fclose(fp);


}


void test2(){

    FILE* fp = fopen("fprintf.txt", "r");
    if (fp!=NULL) {

        //格式化写入
        int productId = 0;
        float productPrice = 0.0f;
        char productTitle[50];
        char productTitleImg[50];

        fscanf(fp,"%d:%f,%s\n%s",&productId,&productPrice,productTitle,productTitleImg);

        printf("产品编号:%d\n",productId);
        printf("产品价格:¥%.2f\n",productPrice);
        printf("产品名称:%s\n",productTitle);
        printf("产品图片:%s\n",productTitleImg);

    }
        fclose(fp);

}

int main(int argc, const char * argv[]) {


    test2();

    return 0;
}

4.应用:向文件中读取和写入一个二维数组


#include 

int main(int argc, const char * argv[]) {
    //使用fprintf和fscanf函数 将一个二维数组逐行写入到文件中,并读取出来。

    //1、定义二维数组
    int a[3][2]={1,2,3,4,5,6};

    //2、定义文件指针
    FILE *fp = fopen("saveArray.txt", "w+");

    //3、判断
    if (fp!=NULL) {


    //4、格式化的写入   1,2#
        for (int i=0; i<3; i++) {
            fprintf(fp,"%d,%d#",a[i][0],a[i][1]);
        }

    //5、拉回指针
        rewind(fp);

    //6、定义数组,接收读取的内容
        int array[3][2];

    //7、循环读取
        for (int i=0; i<3; i++) {
            fscanf(fp, "%d,%d#",&array[i][0],&array[i][1]);
            printf("%d\t\t%d\n",array[i][0],array[i][1]);

            printf("-------------------\n");
        }

    //    显示出来

    }
    //关闭文件指针
    fclose(fp);
    fp = NULL;

    return 0;
}

5.文件的随机读写

#include 

int main(int argc, const char * argv[]) {

    //从二进制文件student.data(160)个字节
    //读取第二个学生的信息

    // 先定义结构体
    struct Student {
        char name[20];
        char sex;
        int age;
        float score;
    };
    // 定义结构体变量保存读取出来的学生信息

    struct Student stu;

    //1、定义文件指针,并且打开文件
    FILE *fp = fopen("student.data", "r");
    //2、判断
    if (fp!=NULL) {

    //3、移动文件内内部指针
        fseek(fp, sizeof(stu)*2, SEEK_SET);  //SEEK_SET也可以换成0

    //4、读取
        fread(&stu,sizeof(stu),1,fp);

    //5、显示出来
        printf("%d,%c,%.2f,%s\n",stu.age,stu.sex,stu.score,stu.name);
    }
    //关闭文件指针
    fclose(fp);
    return 0;
}

6.内存分区

内存从高到低依次是:
栈: 存放临时创建的局部变量
堆:存放进程运行中被动态分配的内存段
BSS段:存放程序中未初始化的全局变量和静态变量
数据段:用来存放已初始化的全局变量和静态变量
代码段:存放程序执行代码的一块内存区域

7.综合应用:通讯录的实现

//  main.c
//  C15-通讯录


#include 
//1、导入头文件
#include 
//定义宏(联系人数组的长度,姓名长度、电话号码长度)
#define NAME_LEN 22
#define TELNUM_LEN 16
#define LEN 100
//定义联系人结构体
typedef struct {
    //定义联系人姓名
    char name[NAME_LEN];

    //定义联系人的电话号码
    char telNum[TELNUM_LEN];
} Person;   //给结构体起一个别名

//定义联系人数组
Person contacts[LEN];
//定义变量保存联系人个数
int totalContactCount = 0;
//定义变量保存文件的名称
char *filePath = "telbook.data";

//定义函数,并且声明
void doAdd();
void doDelete();
void doUpdate();
void doList();
void doSearchByName();
void init();
void writeToFile();


//选择不同的功能,调用不同的函数

int main(int argc, const char * argv[]) {

    int num=0;
    //调用初始化方法
    init();

    int flag = 1;  //退出标志
    while (flag) {

        //编写控制程序
        printf("\n\n**************************\n");
        printf("****** 欢迎使用通讯录 ******\n");
        printf("****** 1、添加联系人  ******\n");
        printf("****** 2、删除联系人  ******\n");
        printf("****** 3、修改联系人  ******\n");
        printf("****** 4、查看所有联系人 ****\n");
        printf("****** 5、搜索联系人  ******\n");
        printf("****** 6、退出系统    ******\n");
        printf("**************************\n\n");

        printf("请输入1-6之间的序号,选择要执行的功能\n");
        //接收用户输入的编号
        scanf("%d",&num);
        //判断输入的序号是否合法
        if(num<1 || num >6){
            printf("输入错误!\n");

        }else{

            //根据用户输入的编号,执行不同的功能
            switch (num) {
                case 1:
                    doAdd();
                    break;
                case 2:

                    doDelete();
                    break;
                case 3:

                    doUpdate();
                    break;
                case 4:
                    doList();
                    break;
                case 5:

                    doSearchByName();
                    break;
                case 6:

                    printf("正在退出系统...\n");
                    printf("系统已经退出!\n");

                    //return 0;
                    flag = 0;

                    break;

                default:
                    break;
            }

        }
    }
    return 0;
}

/**
 *  添加联系人
    1) 提示用户输入联系人信息
    2)接收联系人信息
    3)提示输入电话号码信息
    4)接收电话号码

    5)让用户再次确认添加联系人    1 确认  0 取消
    6)保存联系人信息到 联系人数组中
    7)让联系人的个数+1

    8) 把最新的数组,重新保存到文件中
 */
void doAdd(){

    printf("您正在执行的是添加联系人的操作:\n");

//    1) 提示用户输入联系人信息
    printf("请输入联系人姓名:     [*联系人姓名中间不能有空格]\n");
//    2)接收联系人信息   //contacts[1].name
    char name[NAME_LEN];
    char telNum[TELNUM_LEN];

    scanf("%s",name);
//    3)提示输入电话号码信息
    printf("请输入联系人电话号码:  [*联系人号码中间不能有空格]\n");
    //4)接收电话号码
    scanf("%s",telNum);


//    5)让用户再次确认添加联系人    1 确认  0 取消
    int nn;
    printf("您确定要添加这个联系人吗? 0.取消  1.确认\n");
    scanf("%d",&nn);
    if (nn) {
//    6)保存联系人信息到 联系人数组中
        strcpy(contacts[totalContactCount].name, name);
        strcpy(contacts[totalContactCount].telNum, telNum);
//    7)让联系人的个数+1
        totalContactCount++;
//    8) 把最新的数组,重新保存到文件中

        writeToFile();
    }
    printf("联系人添加成功!\n");
}


/**
 *  删除联系人
    1)提示用户输入一个要删除的联系人的编号
    2)判断编号是否合法
    3)再判断 要删除的元素 是否是数组的最后一个元素
          如果是最后一个元素,总人数-1
          如果不是最后一个元素,也就是中间的元素

          移动元素
           i = 编号   i< 总   i++

              a[编号-1] = a[编号]

          总人数-1

     4)同步写入到文件中
 */
void doDelete(){

    printf("您正在执行的是删除联系人的操作:\n");
    doList();

//    1)提示用户输入一个要删除的联系人的编号
    int  nn;
    printf("请输入一个要删除的联系人的编号:\n");
    scanf("%d",&nn);
//    2)判断编号是否合法
    if (nn <1 || nn > totalContactCount) {
        //如果编号不合法,则return  返回了
        return ;
    }

    int queren=0;
    printf("联系人删除后,无法恢复,请确认是否要删除: 0.取消 1.确认\n");
    scanf("%d",&queren);
    if (queren) {

        //    3)再判断 要删除的元素 是否是数组的最后一个元素
        if(nn == totalContactCount){

            //    如果是最后一个元素,总人数-1
            totalContactCount--;

        }else{

            //    如果不是最后一个元素,也就是中间的元素

            //    移动元素
            //    i = 编号   i< 总   i++
            for (int i = nn; i//nn 是编号,编号比下标大1
                //    a[i-1] = a[i]
                contacts[i-1] = contacts[i];
            }

            //    总人数-1
            totalContactCount--;
        }
        //    4)同步写入到文件中
         writeToFile();
    }


}



/**
 *  修改联系人
    1) 提示用户输入一个联系人的编号
    2) 判断编号是否合法
    3)让用户输入新的联系人姓名和电话
    4) 接收用户的输入

    5)让用户再次确认删除
    6)把原来的姓名和电话进行更新
    7)同步保存到文件中
 */
void doUpdate(){

    printf("您正在执行的是修改联系人的操作:\n");
    //显示所有的联系人
    doList();

//    1)提示用户输入一个要删除的联系人的编号
    int  nn;
    printf("请输入一个要修改的联系人的编号:\n");
    scanf("%d",&nn);
//    2)判断编号是否合法
    if (nn <1 || nn > totalContactCount) {
        //如果编号不合法,则return  返回了
        return ;
    }

    char name[NAME_LEN];
    char telNum[TELNUM_LEN];

//    3)让用户输入新的联系人姓名和电话
    printf("请输入联系人姓名:     [*联系人姓名中间不能有空格]\n");
//    4) 接收用户的输入
    scanf("%s",name);
    printf("请输入联系人电话号码:  [*联系人号码中间不能有空格]\n");
    scanf("%s",telNum);


//    5)让用户再次确认删除
    int queren = 0;
    printf("修改后联系人信息后,数据无法恢复,请确认修改:0.取消  1.确认\n");
    scanf("%d",&queren);

    if (queren) {

//    6)把原来的姓名和电话进行更新
        strcpy(contacts[nn-1].name, name);
        strcpy(contacts[nn-1].telNum, telNum);
//    7)同步保存到文件中
        writeToFile();
    }


}


/**
 *  查询所有的联系人
    思路:
    1)先判断 totalContactCount == 0
      如果等于0 表示没有联系人,提示:通讯录空无一人

         不等于0 打印所有的联系人

    2)循环

    3)遍历输出所有的联系人信息
 */
void doList(){

    printf("您正在执行的是查询所有的联系人的操作:\n");

//    1)先判断 totalContactCount == 0
    if(totalContactCount == 0){
//    如果等于0 表示没有联系人,提示:通讯录空无一人
        printf("您的通讯录还很寂寞!\n");

    }else{

        printf("编号\t\t姓名\t\t\t电话\t\t\n");
//    不等于0 打印所有的联系人
        for (int i=0; i//    2)循环

            //    3)遍历输出所有的联系人信息
            printf("%d\t\t%s\t\t\t%s\t\t\n",i+1,contacts[i].name,contacts[i].telNum);
        }

    }

}


/**
 * 搜索联系人
   1) 提示用户输入一个联系人的姓名
   2)接收这个姓名
   3)循环,遍历数组
      //进行字符串的比较
      //strcmp(contacts[i].name,name) == 0
      //如果查找到了,输出这个联系人的电话号码

      //如果没有查找到,提示:没有查找到

 */
void doSearchByName(){

    printf("您正在执行的是搜索联系人的操作:\n");

//    1) 提示用户输入一个联系人的姓名
    char name[NAME_LEN];
    printf("请输入联系人姓名:     [*联系人姓名中间不能有空格]\n");
//    2)接收这个姓名
    scanf("%s",name);

//    3)循环,遍历数组
    int i;
    for (i=0; i//进行字符串的比较
        //strcmp(contacts[i].name,name) == 0
        if (strcmp(contacts[i].name, name)==0) {

            //如果查找到了,输出这个联系人的电话号码
            printf("您要查找的联系人: %s 的电话是: %s \n",name,contacts[i].telNum);
            //查找到了以后,停止
            break;
        }

    }

    //如果没有查找到,提示:没有查找到
    if (i==totalContactCount) {
        printf("对不起,没有查找到%s这个人!",name);
    }
}


/**
 *  初始化函数
    思路:

    1)定义文件指针,并且(尝试)打开文件
    2)如果能够打开这个文件(说明文件已经存在了)

          i.把文件中存放联系人数量读取出来
          ii.根据联系人的数量,把联系人信息全部读取出来,放到联系人数组中

       如果文件打开失败了

          i.创建文件
          ii.写入联系人数量  0

    3)关闭文件指针
 */
void init(){

    printf("系统正在初始化...\n");

//    1)定义文件指针,并且(尝试)打开文件
    FILE *fp = fopen(filePath, "r");
//    2)如果能够打开这个文件(说明文件已经存在了)
//
    if (fp!=NULL) {

//    i.把文件中存放联系人数量读取出来
        fread(&totalContactCount, sizeof(totalContactCount), 1, fp);
//    ii.根据联系人的数量,把联系人信息全部读取出来,放到联系人数组中
        for (int i=0; i//依次读取每个联系人的信息
            //contacts[0]
            fread(&contacts[i], sizeof(Person), 1, fp);
        }
//
    }else{
//    如果文件打开失败了
//    
//    i.创建文件
        fp = fopen(filePath, "w");
//    ii.写入联系人数量  0
//        totalContactCount
        fwrite(&totalContactCount, sizeof(totalContactCount), 1, fp);

        printf("通讯录数据文件创建成功!\n");
//
    }
//    3)关闭文件指针
    fclose(fp);
    fp = NULL;

    printf("系统初始化完成!\n");

}


/**
 *  把数组的内容重新写入到文件中
    1)打开文件,w
    2)判断是否打开成功
    3)先把联系人的数量写入到文件中
    4)把每个联系人的数据,都写入到文件中

    5)关闭文件
 */
void writeToFile(){

//    1)打开文件,w
    FILE *fp = fopen(filePath, "w");
//    2)判断是否打开成功
    if (fp!=NULL) {

//    3)先把联系人的数量写入到文件中
        // 1
        fwrite(&totalContactCount, sizeof(totalContactCount), 1, fp);
//    4)把每个联系人的数据,都写入到文件中
        for (int i=0; i//每次写入一个联系人数据
            fwrite(&contacts[i], sizeof(Person), 1, fp);
        }
//
        printf("数据更新完成!\n");
    }
//    5)关闭文件
    fclose(fp);

}

你可能感兴趣的:(c,通讯录,c语言)