学习笔记8-C语言文件

文件

       文件:存储在外部介质上的数据集合。集合的名称叫文件名。

作用:文件可以保存程序运行结果。

 

编码分类:ascii文件(文本文件)和二进制文件。

文件操作原理:

1) 文件缓冲区:系统为文件自动的在内存区中为使用的文件开辟的缓冲区。

2) 输入输出流:数据的输入输出。

1 文件操作步骤:

1) 引入头文件 stdio.h

2) 定义文件指针

3) 打开文件

4) 文件读写

5) 关闭文件

2 文件相关函数

字符读写函数:fgetc和fputc

字符串读写函数:fgets和fputs

数据块读写函数:fread 和fwrite

格式化读写函数:fscanf和fprintf

3 文件指针

       FILE *指针变量标识符;

文件指针指向文件在内存的首地址。

1) 文件打开(fopen)

打开文件是建立文件的各种信息,并使文件指针指向该文件,以便进行其他操作。

FILE *fp=NULL;   //定义文件指针并赋值为NULL

fp=fopen(文件名,文件使用方式);

成功返回文件首地址,否则为NULL。

2) 文件关闭(fclose)

断开指针与文件的联系。

fclose(fp);

4文件使用方式

       r  只读

w 只写  创建或者先删后建文件。

a  只写  文件存在追加,不存在创建。换行追加

r+ 读写

w+读写 创建文件或者覆盖文件

a+ 读写 等价a但是可以读。

t  打开文件文件  默认打开文本文件。

b  打开二进制文件

 

注意

凡是以 r 打开的文件,文件必须存在。

打开文件失败是 返回NULL。

文本文件读入内存时需要将ascii转换为二进制。写入时相反。对二进制读写不需要转换。

5 文件函数使用

1) 字符读写函数

单位:字节

fputc(字符,文件指针);//把字符写入文件。

使用循环写入字符串。

 

读取一个字符

fgetc(fp);

 

char s=fgetc(fp);

while(s!=EOF){  //EOF 文件结束标志

s=fgetc(fp);   //文件指针会自动向后移动

putchar(s);

}

 

rewind(fp)将文件指针重新指向文件首地址。

 

2) 字符串读写

fputs(字符串,文件指针);

返回值为写入的字节数。

 

char str[100];

fgets(数组名称;sizeof(str),fp); //一次读取数组的长度个字节

1)文件读取完成后会给字符串数组加 \0  。

2)遇到\n或者EOF读取结束。  每次读取一行。

 

一个汉字 3个字节

一个字符1个字节

 

3) 数据块读写函数

fwrite(写入数据的首地址,块大小,块数,文件指针);

fread(数组首地址,块大小,块数,文件指针);

 

文件与结构体

写结构体

struct Student{
char name[20];
int age;
}stu[10];
fwrite(结构体变量地址,结构体大小,1,fp);
 
for(int i=0;i<10;i++){
fwrite(&stu[i],sizeof(structStudent),1,fp);
 
}


读结构体

struct Stuent stu2[10];
 
for(int i=0;i<10;i++){
 
fread(&stu2[i],sizeof(structStudent),1,fp);
 
}
 


 

4) 格式化读写函数

 

fscanf(文件指针,格式字符串,输入列表);

fscanf(fp,“%d%d”,&i,&j);

 

fprintf(文件指针,格式字符串,输入列表);

fprintf(fp,“%d%d”,i,j);

 

 

5)文件随机读写函数

fseek 移动文件内部的位置指针

 

fseek(文件指针,位移量,起始点);

位移量:移动的字节    long型数据数字后加L

起始点:从哪开始移动

              文件首部     SEEK_SET  0

              文件当前位置SEEK_CUR  1

              文件末尾       SEEK_END 2

6)文件检测函数

       feof(文件指针)

       判断指针是否指向文件结束位置。 返回值 :结束是1 没结束为0。

       ferror 文件出错检测函数。

      

 

文件操作实例

简易通讯录

//
//  main.c
//  通讯录
//
//  Created by ywxkdz on 15/11/19.
//  Copyright (c) 2015年 itcast. All rights reserved.
//

#include <stdio.h>
#include <string.h>
#define LEN 100     //通讯录容量
#define NAMELEN 21  //姓名长度
#define TELNUMLEN 12 //电话长度

//联系人结构体
typedef struct person {
    char name[NAMELEN];
    char telNum[TELNUMLEN];
}Person;
//定义通讯录数组
Person contacts[LEN];

//定义联系人总记录数
int totalCount=0;
//接收用户输入的编号

//联系保存的文件名
char *filePath="telbook.data";

int no=-1;   //全局变量接收用户选择的功能

int flag;   //全局变量 接收用户对操作的确认

//函数声明
void printFirstPage();
int  validateInputNo();
void addContacts();
void delContacts();
void updateContacts();
void listContacts();
void searchContacts();
void initContcats();
void writeFile();


int main(int argc, const char * argv[]) {
    flag=0;
    while(1){
        initContcats();
        printFirstPage();
        int no=validateInputNo();
        switch (no) {
            case 1:
                addContacts();
                break;
            case 2:
                delContacts();
                break;
            case 3:
                updateContacts();
                break;
            case 4:
                listContacts();
                break;
            case 5:
                searchContacts();
                break;
            case 0:
                return 0;
                break;
                
            default:
                break;
        }
        
    }
   
   
    
    
    return 0;
}

void printFirstPage(){
    
    printf("****************************\n");
    printf("*********欢迎使用通讯录********\n");
    printf("**********1 添加联系人********\n");
    printf("**********2 删除联系人********\n");
    printf("**********3 修改联系人********\n");
    printf("**********4 查看联系人********\n");
    printf("**********5 搜索联系人********\n");
    printf("**********0 退出系统**********\n");
    printf("****************************\n");

    
}
/**
 *  提示用户输入功能选项编号 并检验是否合法
 *
 *  @return 合法的选项返回选项编号 不合法的返回-1
 */
int  validateInputNo(){
    
    printf("请输入0-5之间的编号\n");
    scanf("%d",&no);
    
    if (no>5||no<0) {
        printf("输入不合法请重新输入\n");
        
        return -1;
    }
    
    return no;
    
}
/**添加联系人
 *
 */
void addContacts(){
    
    //提示用户输入联系人姓名并接收
    printf("请输入联系人姓名\n");
    scanf("%s",contacts[totalCount].name);
    //提示用户输入联系人电话号码并接收
    printf("请输入联系人电话号码\n");
    scanf("%s",contacts[totalCount].telNum);
    
    //输出用户输入的信息,提示用户是否添加
    printf("你添加的联系人是:%s,电话号码是:%s\n",contacts[totalCount].name,contacts[totalCount].telNum );
    printf("是否添加?1:是 0:否\n");
    scanf("%d",&flag);
    
   
    if (flag) {
         //电话记录条数+1 用户信息写入文件
        totalCount++;
        writeFile();
    }else{
        printf("你已经取消添加\n");
    }
    
    
    
}
/**
 *  根据用户选择,删除联系人
 */
void delContacts(){
    //列出所有联系人,提示用户选择删除的联系人编号 并接收
    listContacts();
    printf("请选择将要删除的联系人id\n");
    scanf("%d",&no);
    if (no<0||no>totalCount) {
        //非法输入提示
        printf("你输入的编号有误请重新操作\n");
    }else if (no==totalCount){
        //如果用户输入的编号是最后一个,直接将记录数-1 最后一个不保存即可完成删除操作。
        printf("你选择的\n id:%d \t name:%s \t telNum:%s\n",no,contacts[no-1].name,contacts[no-1].telNum);
        printf("是否删除?1 是 0 否\n");
        scanf("%d",&flag);
        if (flag) {
            totalCount--;
            writeFile();
        }

    }else{
         //如果用户输入的编号不是最后一个,需将这个id之后的数据向前挪一个位置。
        printf("你选择的\n id:%d \t name:%s \t telNum:%s\n",no,contacts[no-1].name,contacts[no-1].telNum);
        printf("是否删除?1 是 0 否\n");
        scanf("%d",&flag);
        if (flag) {
            for (int i=no; i<totalCount; i++) {
                
                contacts[i-1]=contacts[i];
                
            }
            totalCount--;
            writeFile();
        }
    
    }
    
    
}
/**
 *  根据用户输入信息修改联系人电话号码
 */
void updateContacts(){
    listContacts();
    printf("请选择你要修改联系人的id\n");
    scanf("%d",&no);
    
    if (0<no &&no<totalCount) {
        
        //打印用户修改之前的联系人信息和用户将要修改的联系人信息,提示用户选择是否修改并接收
        printf("你选择的\n id:%d \t name:%s \t telNum:%s\n",no,contacts[no-1].name,contacts[no-1].telNum);
        printf("请输入你修改之后的电话号码\n");
        char str[TELNUMLEN];
        scanf("%s",str);
        printf("修改之后的信息为\nname:%s \t telNum:%s\n",contacts[no-1].name,str);
        printf("是否修改?1 是 0 否\n");
        scanf("%d",&flag);
        if (flag) {
            //对联系人电话号码重新赋值
            strcpy(contacts[no-1].telNum, str);
            writeFile() ;
        }
        
    }else{
        printf("你输入的id有误,请重新操作");
    }
    

}
/**
 *  根据姓名查找联系人
 */
void searchContacts(){
    
    printf("请输入你要查找的联系人姓名\n");
    char name[NAMELEN];
    scanf("%s",name);
    flag =0;
    //联系人姓名匹配  匹配一个 flag +1
    for (int i=0; i<totalCount; i++) {
        
        if (strcmp(contacts[i].name, name)==0) {
          printf("你查找的\n id:%d \t name:%s \t telNum:%s\n",i+1,contacts[i].name,contacts[i].telNum);
            flag++;
            
        }
    }
    if (flag==0) {
        //未查找到联系人
        printf("你查找的联系人不存在\n");
    }
    
}
/**
 *  打印联系人列表
 */
void listContacts(){
    
    if (totalCount==0) {
        
        printf("通讯录为空,请添加联系人\n");
        
        
    }else{
        
        for (int i=0; i<totalCount; i++) {
            
            printf("id:%d\t name:%s\t telNum:%s\n",i+1,contacts[i].name,contacts[i].telNum);
            
        }
        
        
    }
    
    
}

/**
 *初始化联系人文件和联系人数组
 *如果联系人文件不存在 创建该文件
 *如果联系人文件存在,先读取联系人总记录数赋值给 totalCount
                    再循环读取所有的联系人信息初始化数组
 
 
 */
void initContcats(){
    
    //文件指针定义和打开文件
    FILE *fp=fopen(filePath, "r");
    
    if (fp!=NULL) {
        
        //读取联系人总记录数
        fread(&totalCount, sizeof(totalCount), 1, fp);
        
        //循环读取所有的联系人信息初始化数组
        for (int i=0; i<totalCount; i++) {
            
            fread(&contacts[i], sizeof(Person), 1, fp);
        }
        
        
    }else {
        
        //创建文件写入记录数  当前记录数为 0
        fp=fopen(filePath, "wb");
        
        fwrite(&totalCount, sizeof(totalCount), 1, fp);
        printf("创建通讯录成功\n");
        
    }
    //关闭文件指针
    fclose(fp);
    
    
}

/**
 *  将总记录数和联系人信息写入文件
 */
void writeFile(){
    FILE *fp=fopen(filePath, "wb");
    if (fp!=NULL) {
        //写总记录数
        fwrite(&totalCount, sizeof(totalCount), 1, fp);
        //循环 写联系人信息
        for (int i=0; i<totalCount; i++) {
            fwrite(&contacts[i], sizeof(Person), 1, fp);
        }
    }
    
    fclose(fp);
}






 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值