文件FILE及文件指针

一、文件操作函数

c语言的FILE(大写),其类型声明,在stdio.h中

struct _iobuf {
         char *_ptr;
         int   _cnt;
         char *_base;
         int   _flag;
         int   _file;
         int   _charbuf;
         int   _bufsiz;
         char *_tmpfname;
         };
 typedef struct _iobuf FILE;

文件指针,是指向该结构体类型的指针

FILE *fp; //定义一个文件指针变量

一旦通过函数打开或创建一个文件,指针指向文件,通过指针变量可以对文件进行各种操作

文件操作之前需要打开文件,结束后需要关闭文件

FILE *fopen(const char *filename, const char *mode);

参数filename表示文件名,可以是相对路径,也可以是绝对路径

参数mode表示操作模式,针对文本文件、二进制文件分别如下:

文本文件二进制文件含义
"r"或"rt""rb"只读打开一个文件,文件不存在,打开失败
"r+"或"rt+"或"r+t""rb+"或"r+b"读写打开一个文件,文件不存在,打开失败  
"w"或"wt""wb"只写创建一个新文件,文件存在,覆盖旧文件
"w+"或"wt+"或"w+t""wb+"或"w+b"读写创建一个新文件,文件存在,覆盖旧文件
"a"或"at""ab"追加打开一个文件,文件不存在,创建一个新文件
"a+"或"at+"或"a+t""ab+"或"a+b"追加读打开一个文件,文件不存在,创建一个新文件

试例 

FILE *fp1,*fp2; //定义文件指针变量
fp1=fopen("IN.TXT","r"); //打开一个(已存在的)文本文件IN.TXT
fp2=fopen("OUT.DAT","wb"); //创建一个新二进制文件OUT.DAT

通常,系统会为每个程序自动定义并打开三个标准文件,分别是标准输入文件stdin(键盘)、

标准输出文件stdout(显 示器)、标准出错输出stderr(显示器),程序可直接使用它们

//0.打开关闭文件
FILE * fopen ( const char * filename, const char * mode );
int fclose ( FILE * stream );
//1.读写一个字符
int fgetc ( FILE * stream );
int fputc ( int character, FILE * stream );
//2.读num-1个字符或读到回车或文件结尾,写一个字符串到文件
char * fgets ( char * str, int num, FILE * stream );
int fputs ( const char * str, FILE * stream );
//3.二进制读写
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
//4.格式读写
int fscanf ( FILE * stream, const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );
//5.文件指针移动
void rewind ( FILE * stream );
int fseek ( FILE * stream, long int offset, int origin );
long int ftell ( FILE * stream );
int fgetpos ( FILE * stream, fpos_t * pos );
int fsetpos ( FILE * stream, const fpos_t * pos );

二、文件操作案例:学生管理系统(1)

修正了某同学提供的学生管理系统(使用 fopen fwrite fread 函数)半成品,函数名等尊重原著,并添加了注释

  第一次修改

/* 
学生管理系统——C语言

注:从文件读到内存是input,从内存写到文件是output
fopen fwrite fread 函数请参考: http://www.cplusplus.com/reference/cstdio/fopen/

学生管理系统设计成7个模块,采取文件读写操作实现,文件及数组最多存储数N,设定为5

0.系统帮助说明     
1.输入学生信息    fwrite写入文件, fopen("student","a");    在文件尾写入,若文件不存在,创建文件
    append: Open file for output at the end of a file. Output operations always write data at the end of the file, expanding it. Repositioning operations (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist.
2.查询学生信息  fread读取文件,显示,fopen("student","r");  文件不存在会打开失败,不会创建文件
    read: Open file for input operations. The file must exist.
3.修改学生信息  fread读取文件,修改后,fwrite写入文件,覆盖文件,fopen("student","w");
    write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
4.按学号删信息  fread读取文件,删除后,fwrite写入文件,,fopen("student","w");
    write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
5.显示当前信息  fread读取文件,显示,fopen("student","r");  文件不存在会打开失败,不会创建文件
    read: Open file for input operations. The file must exist.
6.退出系统 

 */

#include <conio.h>   /* getch 头文件 */  
#include<stdio.h>      /*I/o函数*/
#include<stdlib.h>   /*其他说明*/
#include<string.h>   /*字符串函数*/

#define N  5        /*最大学生人数*/

struct record         /*声明结构体*/
{
    char code[20];     /*学号*/
    char name[10];     /*姓名*/
    char sex[5];       /*性别*/
    char time[20];     /*出生年月*/
    char add[20];      /*宿舍号码*/
    char tel[20];      /*电话*/
    char re[20];       /*是否重修*/
};

int k=1;        /* 全局变量k,表示在主函数内循环是否持续 */

/* 函数声明 */
void huanyingyemian(); /* 欢迎函数 使用一次*/

void caidan();  /* 菜单函数 */

void help();    /* 帮助函数 */
void shuru();   /* 输入函数 */  /* 没有单独创建,文件尾部写入函数 */

void xiugai();  /* 修改函数 */  /* 调用读取和写入文件函数 */
void shanchu(); /* 删除函数 */  /* 调用读取和写入文件函数 */

void chazhao(); /* 查找函数 */  /* 调用读取文件到数组函数 */
void xianshi(); /* 显示函数 */  /* 调用读取文件按到数组函数 */

void tuichuxitong(); /* 退出系统 */

int duqu(struct record stu[]);        /* 读取文件到数组函数 */
void fugai(struct record stu[],int n); /* 覆盖写入文件函数*/

int main()
{
    system("cls");
    huanyingyemian();/*  欢迎页面 */
    system("pause");
    
    while(k)  /* k不为0死循环 */
    {        
        system("cls");  /* 清屏 */
        caidan();         /*  主菜单 */
    }
    return 0;
}
 
void huanyingyemian()   /* 欢迎页面 */
{   
    system("COLOR 6f");  /* 背景色 */
    printf("\n");  
    printf("\n");  
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("                               尊敬的用户:您好!\n");     
    printf("\n");      
    printf("\n"); 
    printf("                                   欢迎使用\n");
    printf("\n");   
    printf("\n"); 
    printf("                ▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂\n"); 
    printf("\n"); 
}

void caidan() {   /* 主菜单   */
    int num;       
    system("COLOR 1f");  /* 背景色 */
    printf("\n\n                             学生个人信息管理系统\n\n");  
    printf("\n→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→"); 
    printf("\n"); 
    printf("                      ==============系统功能菜单==============\n"); 
    printf("                      =======友情提醒:查询前请刷新统!========\n"); 
    printf("                      ========================================\n"); 
    printf("                      |======================================|\n"); 
    printf("                      |   0.系统帮助说明     1.输入学生信息  |\n"); 
    printf("                      |--------------------------------------|\n"); 
    printf("                      |   2.查询学生信息     3.修改学生信息  |\n"); 
    printf("                      |--------------------------------------|\n"); 
    printf("                      |   4.按学号删信息     5.显示当前信息  |\n");
    printf("                      |--------------------------------------|\n");         
    printf("                      |--------------------------------------|\n"); 
    printf("                      |             6.退出系统               |\n"); 
    printf("                      |======================================|\n"); 
    printf("                      ========================================\n");
    printf("请选择菜单编号: "); 
    scanf("%d",&num);    
    switch(num) 
    { 
        case 0:system("cls"); help();break;        /* 帮助函数 */
        case 1:system("cls"); shuru();break;       /* 输入函数 */
        case 2:system("cls"); chazhao();break;     /* 查找函数 */
        case 3:system("cls"); xiugai();break;      /* 修改函数 */
        case 4:system("cls"); shanchu();break;     /* 删除函数 */
        case 5:system("cls"); xianshi();break;     /* 显示函数 */
        case 6:system("cls"); k=0;tuichuxitong(); break;   /* 退出主循环,执行退出系统函数  */
        default: printf("请在1--7之间选择\n"); getchar();  /* 清除错误输入字符 */
    }  
}

void help()  /* 帮助函数 */
{       
    system("COLOR 2f");  /* 背景色 */
    printf("\n  尊敬的用户您好!");
    printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n");
    printf("|                                                          |");
    printf("\n  |                  欢迎进入帮助系统!                       |\n");
    printf("|                                                          |");
    printf("\n  |   ★    ★    ★    ★    ★    ★    ★    ★    ★     |\n");
    printf("|                                                          |");
    printf("\n  |             请按照菜单提示进入数字代号!                  |\n");
    printf("|                                                          |");
    printf("\n  |                   谢谢您的使用!                          |\n");
    printf("|                                                          |");
    printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n");
}



void shuru()           /*  实现录入学生基本信息功能 (插入到文件尾部) */
{
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n; /* 表示输入的数据个数 */
    int i,flag=1;
    FILE *fp=fopen("student","a"); /* 在文件尾写入,若文件不存在,创建文件 */
    
    while(flag)
    {
        flag=0;   /* 正确输入n退出循环 */
        printf("请输入需要创建信息的学生人数(1-N,程序设定N为5):\n");
        scanf("%d",&n);
        if(n<1||n>N)
        {
            flag=1;
            printf("输入错误,检查后请重新输入!\n");
        }
    }
    
    /* 文件存储限制为5 */
    if( duqu(stu)+n > N){
        printf("超过文件最大存储\n");
        exit(0);
    }
    
    for(i=0;i<n;i++)
    {
        printf("请输入第%d个学生的基本信息:\n",i+1);
        printf("请输入学号:\n");
        scanf("%s",stu[i].code);
        printf("请输入姓名:\n"); 
        scanf("%s",stu[i].name);
        getchar();
        printf("请输入性别(男,女):\n");
        scanf("%s",stu[i].sex);
        printf("请输入出生年月(输入格式:年.月):\n");
        scanf("%s",stu[i].time);
        printf("请输入宿舍号码:\n");
        scanf("%s",stu[i].add);
        printf("请输入电话号码:\n"); 
        scanf("%s",stu[i].tel); 
        printf("请输入是否重修:\n"); 
        scanf("%s",stu[i].re); 
        fwrite(&stu[i],sizeof(struct record),1,fp);  /* 写入文件 */
    } 
    
    fclose(fp);
    printf("录入完毕!\n");                 
}



/* ****************************** */
void fugai(struct record stu[], int n)        /*从数组保存到文件 (覆盖文件)*/ 
{ 
    FILE *fp; 
    if((fp=fopen("student","w"))==NULL)       /*文件打开是否成功*/ 
    { 
        printf("文件打开失败!\n"); 
        exit(0);                              /*退出系统*/
    }
    
    if(fwrite(stu, n*sizeof(struct record), 1, fp)!=n) /*将内存中的学生信息写入到磁盘文件中*/ 
        printf("文件输入错误!\n"); 
    fclose(fp);                             /*关闭文件*/ 
} 
 
int duqu(struct record stu[])   /* 从文件读取到数组 ,返回读取数据个数*/
{
    int i = 0; 
    FILE *fp; 
    if((fp=fopen("student","r"))==NULL)       /*判断文件是否能够打开成功*/ 
    { 
        printf("文件不存在或不能打开,请按任意键继续!\n"); 
        return -1;  /* 打不开文件,返回读取的数据为 -1 */
    }
    
    while(!feof(fp)){   /* 是否到文件尾 */
        fread(&stu[i++],sizeof(struct record),1,fp); /*将文件中的学生信息读到数组中*/
    }
                                       
    fclose(fp); 
    return i-1;  /* 返回读取数据个数 */  /*  因为到文件尾后进入了循环,所以要-1  */
}

/* ************************************* */



void chazhao()   /* 查找函数 */
{ 
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n = duqu(stu);  /* 读取到数组 */
    if(n==-1) {        
        getch(); /* 为在刷屏之前显示提示信息 */
        return;/* 如果文件不存在或无数据返回 */
    }

    int i,t,flag; 
    char s1[30];  
    system("COLOR 5f"); 
    printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n"); 
    printf("                          1.按学号查询          |\n"); 
    printf("                          2.按姓名查询          |\n"); 
    printf("                          3.退出本菜单          |\n"); 
    printf("〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n"); 
    
    while(1)
    { 
        flag=0; 
        printf("                请输入子菜单编号: "); 
        scanf("%d",&t);  
        switch(t) 
        {  
        case 1: 
            printf("                请输入要查询的学生的学号: \n"); 
            scanf("%s",s1); 
            for(i=0;i<n;i++) 
            if(strcmp(stu[i].code,s1)==0) 
            {  
                flag=1;
                printf("学生学号    学生姓名    性别     出生年月      宿舍号码     电话       是否重修   \n"); 
                printf("\n================================================================================\n"); 
                printf("%6s %7s %5s %9s %8s %10s %14s\n", stu[i].code,stu[i].name,stu[i].sex,stu[i].time,  stu[i].add,stu[i].tel,stu[i].re); 
            } 
            if(flag==0) 
                printf("该学号不存在!  \n");
            break;
        case 2: 
            printf("                请输入要查询的学生的姓名: \n"); 
            scanf("%s",s1); 
            for(i=0;i<n;i++) 
            if(strcmp(stu[i].name,s1)==0) 
            {   
                flag=1; 
                printf("学生学号    学生姓名   性别    出生年月     宿舍号码     电话        是否重修  \n");         
                printf("================================================================================\n"); 
                printf("%6s %7s %5s %9s %8s %10s %14s\n", stu[i].code,stu[i].name,stu[i].sex,stu[i].time,stu[i].add,stu[i].tel,stu[i].re);
            } 
            if(flag==0) 
                printf("该姓名不存在!\n");
            break; 
        case 3:  
            return;   /* 退出本菜单 */
        default: 
            printf("请在1--3之间选择\n"); 
        }
    } 
}

void xiugai() /* 修改函数 */
{ 
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n = duqu(stu);  /* 读取到数组 */
    if(n==-1) {        
        getch(); /* 为在刷屏之前显示提示信息 */
        return;/* 如果文件不存在或无数据返回 */
    }
     
    int i,t,num=0; 
    char sex1[3],s1[30],s2[30];
    
    printf("                请输入要修改的学生的学号:\n");  
    int flag = 1;
    
    scanf("%s",s1);  
    for(i=0;i<n;i++){
        if(strcmp(stu[i].code,s1)==0){
            num=i;
            flag = 0;
            break;
        }     
    }
    if(flag){
        printf("                该学号不存在,按任意键返回!\n");
        getch();
        return;
    }            
                
    system("COLOR 4f");    
    printf("             =============================================\n"); 
    printf("             |               1.修改姓名                  |\n"); 
    printf("             |               2.修改性别                  |\n"); 
    printf("             |               3.修改出生年月              |\n"); 
    printf("             |               4.修改宿舍号码              |\n"); 
    printf("             |               5.修改电话号码              |\n"); 
    printf("             |               6.修改是否重修              |\n"); 
    printf("             |               7.修改退出本菜单            |\n"); 
    printf("             =============================================\n");  
    
    while(1) 
    { 
        printf("请输入子菜单的编号:");  
        scanf("%d",&t); 
        if(t==7) break; /* 修改退出本菜单  */  
        
        switch(t) 
        { 
        case 1: 
            printf("请输入新的姓名:\n");
            scanf("%s",s2); 
            strcpy(stu[num].name,s2);break;  
        case 2: 
            printf("请输入新的性别:\n");   
            scanf("%s",sex1); 
            strcpy(stu[num].sex,sex1);break;  
        case 3: 
            printf("请输入新的出生年月: \n");  
            scanf("%s",s2); 
            strcpy(stu[num].time,s2);break;  
        case 4: 
            printf("请输入新的宿舍号码: \n");      
            scanf("%s",s2); 
            strcpy(stu[num].add,s2);break;  
        case 5: 
            printf("请输入新的电话号码: \n");    
            scanf("%s",s2); 
            strcpy(stu[num].tel,s2);break;  
        case 6: 
            printf("请输入新的是否重修: \n"); 
            scanf("%s",s2); 
            strcpy(stu[num].re,s2);break;  
        default:  
            printf("请在1--7之间选择\n");
        }    
    }     
    fugai(stu,n); /* 保存到文件 */    
}
 
void  shanchu() /* 删除函数 */
{ 
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n = duqu(stu); /* 读取到数组 */
    if(n==-1) {        
        getch(); /* 为在刷屏之前显示提示信息 */
        return;/* 如果文件不存在或无数据返回 */
    }
    
    int i,j,flag=0;   
    char s1[15]; 
    printf("请输入将要删除的学生的学号:\n");  
    scanf("%s",s1);  
    
    for(i=0;i<n;i++){  /* 数组下标从0开始 */
        if(strcmp(stu[i].code,s1)==0)  
        {    
            flag=1; 
            for(j=i;j<n-1;j++) 
                stu[j]=stu[j+1];  
        } 
    } 
    
    if(flag==0){
        printf("                该学号不存在,按任意键返回!\n");
        getch();
        return;
    }
        
    if(flag==1) 
    { 
        printf("                删除成功,按任意键返回!\n"); 
        n--; 
    } 
    fugai(stu,n); /* 保存到文件 */
    getch();
}

void xianshi()  /* 显示函数 */
{
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n = duqu(stu); /* 读取到数组 */
    if(n==-1) {        
        getch(); /* 为在刷屏之前显示提示信息 */
        return;/* 如果文件不存在或无数据返回 */
    }
    
    int j;
    FILE *fp=fopen("student","r"); 
        
    printf("                        所有学生的信息为:\n \n"); 
    printf("学生学号     学生姓名   性别   出生年月     宿舍号码        电话      是否重修       ");   
    printf("\n================================================================================\n");  

    for(j=0; !feof(fp)&&fread( &stu[j],sizeof(struct record), 1, fp ); j++)
    printf("%6s %7s  %5s %9s %8s %10s %14s\n", stu[j].code,stu[j].name,stu[j].sex,stu[j].time,stu[j].add,stu[j].tel,stu[j].re); 
    printf("请按任意键返回"); 
    getch();  
}
 

void tuichuxitong()  /* 退出系统函数 */
{  
    system("COLOR 3f");   /* 背景色提示退出系统 */
    printf("                     -------已退出系统,按任意键结束--------\n\n\n"); 
}

三、文件操作案例:学生管理系统(2)  

第二次修改

/* 
学生管理系统——C语言 ( 第二次修改,bug修复,简化代码,同时对重复代码抽取成函数 )

注:从文件读到内存是input,从内存写到文件是output
fopen fwrite fread 函数请参考: http://www.cplusplus.com/reference/cstdio/fopen/

学生管理系统设计成7个模块,采取文件读写操作实现,文件及数组最多存储数N,设定为5

0.系统帮助说明     
1.输入学生信息    fwrite写入文件, fopen("student","a");    在文件尾写入,若文件不存在,创建文件
    append: Open file for output at the end of a file. Output operations always write data at the end of the file, expanding it. Repositioning operations (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist.
2.查询学生信息  fread读取文件,显示,fopen("student","r");  文件不存在会打开失败,不会创建文件
    read: Open file for input operations. The file must exist.
3.修改学生信息  fread读取文件,修改后,fwrite写入文件,覆盖文件,fopen("student","w");
    write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
4.按学号删信息  fread读取文件,删除后,fwrite写入文件,,fopen("student","w");
    write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
5.显示当前信息  fread读取文件,显示,fopen("student","r");  文件不存在会打开失败,不会创建文件
    read: Open file for input operations. The file must exist.
6.退出系统 

 */

#include <conio.h>   /* getch 头文件 */  
#include<stdio.h>      /*I/o函数*/
#include<stdlib.h>   /*其他说明*/
#include<string.h>   /*字符串函数*/

#define N  5        /*最大学生人数*/

typedef struct record Record;
struct record         /*声明结构体*/
{
    char code[20];     /*学号*/
    char name[10];     /*姓名*/
    char sex[5];       /*性别*/
    char time[20];     /*出生年月*/
    char add[20];      /*宿舍号码*/
    char tel[20];      /*电话*/
    char re[20];       /*是否重修*/
};

int k=1;        /* 全局变量k,表示在主函数内循环是否持续 */

/* 函数声明 */
void huanyingyemian(); /* 欢迎函数 使用一次*/

void caidan();  /* 菜单函数 */

void help();    /* 帮助函数 */
void shuru();   /* 输入函数 */  /* 没有单独创建,文件尾部写入函数 */

void xiugai();  /* 修改函数 */  /* 调用读取和写入文件函数 */
void shanchu(); /* 删除函数 */  /* 调用读取和写入文件函数 */

void chazhao(); /* 查找函数 */  /* 调用读取文件到数组函数 */
void xianshi(); /* 显示函数 */  /* 调用读取文件按到数组函数 */

void tuichuxitong(); /* 退出系统 */

int duqu(struct record stu[]);        /* 读取文件到数组函数 */
void fugai(struct record stu[],int n); /* 覆盖写入文件函数*/

void printTitle();  //打印记录头部
void printStuInfo(Record& stu);   //打印一个记录
void setRecordValue(Record& stu); //一个记录的录入

int main()
{
    system("cls");
    huanyingyemian();/*  欢迎页面 */
    system("pause");
    
    while(k)  /* k不为0死循环 */
    {        
        system("cls");  /* 清屏 */
        caidan();         /*  主菜单 */
    }
    return 0;
}
 
void huanyingyemian()   /* 欢迎页面 */
{   
    system("COLOR 6f");  /* 背景色 */
    printf("\n");  
    printf("\n");  
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("                               尊敬的用户:您好!\n");     
    printf("\n");      
    printf("\n"); 
    printf("                                   欢迎使用\n");
    printf("\n");   
    printf("\n"); 
    printf("                ▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂\n"); 
    printf("\n"); 
}

void caidan() {   /* 主菜单   */
    int num;       
    system("COLOR 1f");  /* 背景色 */
    printf("\n\n                             学生个人信息管理系统\n\n");  
    printf("\n→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→"); 
    printf("\n"); 
    printf("                      ==============系统功能菜单==============\n"); 
    printf("                      =======友情提醒:查询前请刷新统!========\n"); 
    printf("                      ========================================\n"); 
    printf("                      |======================================|\n"); 
    printf("                      |   0.系统帮助说明     1.输入学生信息  |\n"); 
    printf("                      |--------------------------------------|\n"); 
    printf("                      |   2.查询学生信息     3.修改学生信息  |\n"); 
    printf("                      |--------------------------------------|\n"); 
    printf("                      |   4.按学号删信息     5.显示当前信息  |\n");
    printf("                      |--------------------------------------|\n");         
    printf("                      |--------------------------------------|\n"); 
    printf("                      |             6.退出系统               |\n"); 
    printf("                      |======================================|\n"); 
    printf("                      ========================================\n");
    printf("请选择菜单编号: "); 
    scanf("%d",&num);    
    switch(num) 
    { 
        case 0:system("cls"); help();break;        /* 帮助函数 */
        case 1:system("cls"); shuru();break;       /* 输入函数 */
        case 2:system("cls"); chazhao();break;     /* 查找函数 */
        case 3:system("cls"); xiugai();break;      /* 修改函数 */
        case 4:system("cls"); shanchu();break;     /* 删除函数 */
        case 5:system("cls"); xianshi();break;     /* 显示函数 */
        case 6:system("cls"); k=0;tuichuxitong(); break;   /* 退出主循环,执行退出系统函数  */
        default: printf("请在1--7之间选择\n"); getchar();  /* 清除错误输入字符 */
    }  
}

void help()  /* 帮助函数 */
{       
    system("COLOR 2f");  /* 背景色 */
    printf("\n  尊敬的用户您好!");
    printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n");
    printf("|                                                          |");
    printf("\n  |                  欢迎进入帮助系统!                       |\n");
    printf("|                                                          |");
    printf("\n  |   ★    ★    ★    ★    ★    ★    ★    ★    ★     |\n");
    printf("|                                                          |");
    printf("\n  |             请按照菜单提示进入数字代号!                  |\n");
    printf("|                                                          |");
    printf("\n  |                   谢谢您的使用!                          |\n");
    printf("|                                                          |");
    printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n");
    getch(); //暂停
}

void shuru()           /*  实现录入学生基本信息功能 (插入到文件尾部) */
{
    struct record stu;  /* 用于存储从文件读取的数据 */
    
    int n; /* 表示输入的数据个数 */
    int i,flag=1;
    FILE *fp=fopen("student","a"); /* 在文件尾写入,若文件不存在,创建文件 */
    
    while(flag)
    {
        flag=0;   
        printf("请输入需要创建信息的学生人数(1-N,程序设定N为5):\n");
        scanf("%d",&n);
        if(n<1||n>N)
        {
            flag=1;
            printf("输入错误,检查后请重新输入!\n");
        }
    }
    
    for(i=0;i<n;i++)
    {
        printf("请输入第%d个学生的基本信息:\n",i+1);
        setRecordValue(stu);
        fwrite(&stu,sizeof(struct record),1,fp);  
    } 
    
    fclose(fp);
    printf("录入完毕!\n");                 
}

/* ****************************** */
void fugai(struct record stu[], int n)        /*从数组保存到文件 (覆盖文件)*/ 
{ 
    FILE *fp; 
    if((fp=fopen("student","w"))==NULL)       /*文件打开是否成功*/ 
    { 
        printf("文件打开失败!\n"); 
        exit(0);                              /*退出系统*/
    }
    
    if(fwrite(stu, n*sizeof(struct record), 1, fp)!=n) /*将内存中的学生信息写入到磁盘文件中*/ 
        printf("文件输入错误!\n"); 
    fclose(fp);                             /*关闭文件*/ 
} 
 
int duqu(struct record stu[])   /* 从文件读取到数组 ,返回读取数据个数*/
{
    int i = 0; 
    FILE *fp; 
    if((fp=fopen("student","r"))==NULL)       /*判断文件是否能够打开成功*/ 
    { 
        printf("文件不存在或不能打开,请按任意键继续!\n"); 
        return -1;  /* 打不开文件,返回读取的数据为 -1 */
    }
    
    while(!feof(fp)){   /* 是否到文件尾 */
        fread(&stu[i++],sizeof(struct record),1,fp); /*将文件中的学生信息读到数组中*/
    }
                                       
    fclose(fp); 
    return i-1;  /* 返回读取数据个数 */  /*  因为到文件尾后进入了循环,所以要-1  */
}

/* ************************************* */

void chazhao()   /* 查找函数 */
{ 
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n = duqu(stu);  /* 读取到数组 */
    if(n==-1) {        
        getch(); /* 为在刷屏之前显示提示信息 */
        return;/* 如果文件不存在或无数据返回 */
    }

    int i,t,flag; 
    char s1[30];  
    system("COLOR 5f"); 
    printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n"); 
    printf("                          1.按学号查询          |\n"); 
    printf("                          2.按姓名查询          |\n"); 
    printf("                          3.退出本菜单          |\n"); 
    printf("〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\n"); 
    
    while(1)
    { 
        flag=0; 
        printf("                请输入子菜单编号: "); 
        scanf("%d",&t);  
        switch(t) 
        {  
        case 1: 
            printf("                请输入要查询的学生的学号: \n"); 
            scanf("%s",s1); 
            for(i=0;i<n;i++) 
                if(strcmp(stu[i].code,s1)==0) 
                {  
                    flag=1;
                    printTitle();
                    printStuInfo(stu[i]); 
                } 
            if(flag==0) 
                printf("该学号不存在!  \n");
            break;
        case 2: 
            printf("                请输入要查询的学生的姓名: \n"); 
            scanf("%s",s1); 
            for(i=0;i<n;i++) 
                if(strcmp(stu[i].name,s1)==0) 
                {   
                    flag=1; 
                    printTitle();
                    printStuInfo(stu[i]);
                } 
            if(flag==0) 
                printf("该姓名不存在!\n");
            break; 
        case 3:  
            return;   /* 退出本菜单 */
        default: 
            printf("请在1--3之间选择\n"); 
        }
    } 
}

void xiugai() /* 修改函数 */
{ 
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n = duqu(stu);  /* 读取到数组 */
    if(n==-1) {        
        getch(); /* 为在刷屏之前显示提示信息 */
        return;/* 如果文件不存在或无数据返回 */
    }
     
    int i,t,num=0; 
    char sex1[3],s1[30],s2[30];
    
    printf("                请输入要修改的学生的学号:\n");  
    int flag = 1;
    
    scanf("%s",s1);  
    for(i=0;i<n;i++){
        if(strcmp(stu[i].code,s1)==0){
            num=i;
            flag = 0;
            break;
        }     
    }
    if(flag){
        printf("                该学号不存在,按任意键返回!\n");
        getch();
        return;
    }            
                
    system("COLOR 4f");    
    printf("             =============================================\n"); 
    printf("             |               1.修改姓名                  |\n"); 
    printf("             |               2.修改性别                  |\n"); 
    printf("             |               3.修改出生年月              |\n"); 
    printf("             |               4.修改宿舍号码              |\n"); 
    printf("             |               5.修改电话号码              |\n"); 
    printf("             |               6.修改是否重修              |\n"); 
    printf("             |               7.修改退出本菜单            |\n"); 
    printf("             =============================================\n");  
    
    while(1) 
    { 
        printf("请输入子菜单的编号:");  
        scanf("%d",&t); 
        if(t==7) break; /* 修改退出本菜单  */  
        
        switch(t) 
        { 
        case 1: 
            printf("请输入新的姓名:\n");
            scanf("%s",s2); 
            strcpy(stu[num].name,s2);break;  
        case 2: 
            printf("请输入新的性别:\n");   
            scanf("%s",sex1); 
            strcpy(stu[num].sex,sex1);break;  
        case 3: 
            printf("请输入新的出生年月: \n");  
            scanf("%s",s2); 
            strcpy(stu[num].time,s2);break;  
        case 4: 
            printf("请输入新的宿舍号码: \n");      
            scanf("%s",s2); 
            strcpy(stu[num].add,s2);break;  
        case 5: 
            printf("请输入新的电话号码: \n");    
            scanf("%s",s2); 
            strcpy(stu[num].tel,s2);break;  
        case 6: 
            printf("请输入新的是否重修: \n"); 
            scanf("%s",s2); 
            strcpy(stu[num].re,s2);break;  
        default:  
            printf("请在1--7之间选择\n");
        }    
    }     
    fugai(stu,n); /* 保存到文件 */    
}
 
void  shanchu() /* 删除函数 */
{ 
    struct record stu[N];  /* 用于存储从文件读取的数据 */
    int n = duqu(stu); /* 读取到数组 */
    if(n==-1) {        
        getch(); /* 为在刷屏之前显示提示信息 */
        return;/* 如果文件不存在或无数据返回 */
    }
    
    int i,j,flag=0;   
    char s1[15]; 
    printf("请输入将要删除的学生的学号:\n");  
    scanf("%s",s1);  
    
    for(i=0;i<n;i++){  /* 数组下标从0开始 */
        if(strcmp(stu[i].code,s1)==0)  
        {    
            flag=1; 
            for(j=i;j<n-1;j++) 
                stu[j]=stu[j+1];  
        } 
    } 
    
    if(flag==0){
        printf("                该学号不存在,按任意键返回!\n");
        getch();
        return;
    }
        
    if(flag==1) 
    { 
        printf("                删除成功,按任意键返回!\n"); 
        n--; 
    } 
    fugai(stu,n); /* 保存到文件 */
    getch();
}

void xianshi()  /* 显示函数 */
{
    Record stu;
    int flag=0;
    FILE *fp=fopen("student","r"); 
        
    printf("                        所有学生的信息为:\n \n"); 
    printTitle();

    for( ; !feof(fp)&&fread( &stu,sizeof(struct record), 1, fp ); flag=1 )
        printStuInfo(stu);
    if(!flag)
        printf("无信息\n"); 
    printf("请按任意键返回"); 
    getch();     
}
 
void tuichuxitong()  /* 退出系统函数 */
{  
    system("COLOR 3f");   /* 背景色提示退出系统 */
    printf("                     -------已退出系统,按任意键结束--------\n\n\n"); 
}

void printTitle() /* 打印记录头 */
{
    printf("学生学号     学生姓名   性别   出生年月     宿舍号码        电话      是否重修       ");   
    printf("\n================================================================================\n");      
}

void printStuInfo(Record& stu)  /* 打印一个记录 */
{
    printf("%6s %7s  %5s %9s %8s %10s %14s\n", stu.code,stu.name,stu.sex,stu.time,stu.add,stu.tel,stu.re); 
}

void setRecordValue(Record& stu)
{
        printf("请输入学号:\n");
        scanf("%s",stu.code);
        printf("请输入姓名:\n"); 
        scanf("%s",stu.name);
        getchar();
        printf("请输入性别(男,女):\n");
        scanf("%s",stu.sex);
        printf("请输入出生年月(输入格式:年.月):\n");
        scanf("%s",stu.time);
        printf("请输入宿舍号码:\n");
        scanf("%s",stu.add);
        printf("请输入电话号码:\n"); 
        scanf("%s",stu.tel); 
        printf("请输入是否重修:\n"); 
        scanf("%s",stu.re); 
}

四、文件操作案例:学友花卉管理系统(链式存储)

学友花卉管理系统,使用链表存储,存储文件 .txt

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
 
//flower结构体存储花卉信息 
typedef struct flowers{
   int num;//花卉编号
   char name[10];//花卉名称 
   char type[10];//花卉科属 
   int price;//花卉价格
}ElemType;
 
typedef struct LNode{//定义节点 
    ElemType data;   //数据域 
    struct LNode *next;     //指针域 
}LNode, *LinkList;
//函数声明 
void Welcome(); /* 欢迎函数 使用一次*/
void CreateList(LinkList *L);                    //创建链表 
void NodeAppend(LinkList *L, ElemType e);         //增加节点 
int NodeDelete(LinkList *L, int num);             //删除节点 
int NodeModify(LinkList *L, int num, ElemType e);//修改节点 
int NodeSearch(LinkList L, int num, ElemType *e);//查找节点 
void ReadFile(LinkList *L);                         //读取文件 
void WriteFile(LinkList L);                      //写入文件 
void Addflower(LinkList *L);                     //增加花卉 
void Deleteflower(LinkList *L);                 //删除花卉 
void Modifyflower(LinkList *L);                 //修改花卉 
void Searchflower(LinkList L);                     //查找花卉 
void Showflower(LinkList L);                 //显示花卉    
void Menu();                                     //主菜单函数 
 
//创建链表(含头节点) 
void CreateList(LinkList *L)                  // *L指向结构体的指针 
{ 
    *L = (LinkList)malloc(sizeof(LNode));    //计算并分配地址给Node  sizeof计算数据 所占空间  malloc开辟地址 
    (*L) -> next = NULL;          //函数调用完毕后,L指向空链表 
}
 
//尾部增加节点 
void NodeAppend(LinkList *L, ElemType e){
    LNode *q = (LinkList)malloc(sizeof(LNode));            //创建头节点 
    q -> data = e;
    q -> next = NULL;                //初始为空 
    LNode *p = *L;
    while(p -> next) p = p -> next;
    p -> next = q;                    //新节点插入表中 
}
 
//根据编号删除节点 
int NodeDelete(LinkList *L, int num){
    LNode *p,*q;
    p = *L;
    while(p -> next){
        q = p -> next;
        if(num == (q -> data).num){
            p -> next = q -> next;
            free(q);                       //释放地址 
            return 0;
        } 
        p = p -> next;
    }
    return 1;
}
 
//根据编号修改节点 
int NodeModify(LinkList *L, int num, ElemType e){
    LNode *p,*q;
    p = *L;
    while(p -> next){
        q = p -> next;
        if(num == (q -> data).num){
            q -> data = e;
            return 0;
        } 
        p = p -> next;
    }
    return 1;
}
 
//根据编号搜索节点,若找到则将节点信息存储至e并返回 
int NodeSearch(LinkList L, int num, ElemType *e){
    LNode *p, *q;
    p = L;
    while(p -> next){
        q = p -> next;
        if(num == (q -> data).num){
            *e = q -> data;
            return 0;
        } 
        p = p -> next;
    }
    return 1;
}
 

void ReadFile(LinkList *L)                    //读取文件中的数据到链表 
{
    FILE *fp = NULL;
    fp = fopen("flowers.txt", "r");
    if(fp == NULL){
       fp = fopen("flowers.txt","w");
    }
    CreateList(L);
    ElemType temp;
    while(fscanf(fp, "%d %s %s %d", &temp.num, &temp.name,&temp.type, &temp.price) != EOF)         //判断是否读取完毕 
    {
        NodeAppend(L, temp);
    }
    fclose(fp);                 //关闭流 
}
 

void WriteFile(LinkList L)            //将链表中的数据用覆盖的方式写入文件中    
{
    FILE *fp = NULL;
    fp = fopen("flowers.txt", "w");         //文件尾写入   若文件不存在,创建flowers文件 
    LNode *p = L;
    ElemType temp;
    while(p -> next){
        temp = p -> next -> data;
        fprintf(fp, "%d %s %s %d\n", temp.num, temp.name, temp.type,temp.price);
        p = p -> next;
    } 
    fclose(fp);
    printf("\n");  
    printf("\n");  
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    system("COLOR 3f");   //背景色提示退出系统 
    printf("                            -------已退出系统,按任意键结束--------\n\n\n");
}
 

void Addflower(LinkList *L)                //录入花卉信息 
{
    ElemType e;
    printf("请输入要录入的花卉信息:\n");
    printf("编号\t名称\t科属\t价格\n");
    scanf("%d %s %s %d", &e.num, &e.name,&e.type, &e.price);
    NodeAppend(L, e);
    system("pause");
}
 

void Deleteflower(LinkList *L)            //删除花卉信息 
{
    int num;
    printf("请输入要删除的花卉编号:");
    scanf("%d", &num);
    if(NodeDelete(L,num) == 1) 
        printf("未查找到该花卉!\n");
    else 
        printf("删除成功!\n");
    system("pause");
}
 

void Modifyflower(LinkList *L)            //修改花卉信息 
{
    ElemType e;
    int num; 
    printf("请输入要修改的花卉的当前编号:");
    scanf("%d", &num);
    printf("请输入修改后的信息:编号 名称 科属 价格\n");
    scanf("%d %s %s %d", &e.num, &e.name,&e.type, &e.price);
    if(NodeModify(L, num, e) == 1) 
        printf("未查找到该花卉!\n");
    else 
        printf("修改成功!\n");
    system("pause");
}
 

void Searchflower(LinkList L)               //查找花卉信息 
{
    ElemType e;
    int num; 
    printf("请输入要查找的花卉编号:\n");
    scanf("%d", &num);
    if(NodeSearch(L, num, &e) == 1) 
        printf("未查找到改该花卉!\n");
    else 
        printf("编号\t名称\t科属\t价格\n%d \t%s \t%s \t%d\n", e.num, e.name, e.type,e.price);
    system("pause");
}
 

void Showflower(LinkList L)        //显示已输入的花卉信息 
{  
    printf("编号\t名称\t科属\t价格\n");
    LNode *p = L;
    ElemType e;
    while(p -> next){
        e = (p -> next) -> data;
        printf("%d\t%s\t %s\t %d\n", e.num, e.name, e.type, e.price);
        p = p -> next;
    }
    system("pause");
}

void Sort(LinkList& L)
{
    LinkList t,s,r;   
    for(LinkList p = L; p->next->next; p = p->next) //有头结点的链表
    {
        LinkList q = p->next;   //当前结点的指针
        ElemType temp = q->data; //当前结点的数据
        
        for(r = q,s=q; r->next; r = r->next){   //从下一个结点开始
            if( 1== strcmp(temp.name,r->next->data.name)){             //如果发现小于temp的数据
                temp = r->next->data;  //更新数据
                s = r;                 //保存之前结点指针
            }
        }
               
        if(-1==strcmp(s->next->data.name,q->data.name ))//即找到了最小数
        { 
            p->next=s->next; 
            s->next = q;     
            
            t = q->next;    
            
            q->next = p->next->next;    
            p->next->next = t;        
        }        
    }    
}

void Welcome()   /* 欢迎页面 */
{   
    system("COLOR 6f");  /* 背景色 */
    printf("\n");  
    printf("\n");  
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("\n"); 
    printf("                         尊敬的用户:您好!\n");     
    printf("\n");      
    printf("\n"); 
    printf("                                   欢迎使用花卉管理系统\n");
    printf("\n");   
    printf("\n"); 
    printf("                ▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂\n"); 
    printf("\n"); 
}
//主菜单 
void Menu(){
    system("cls");       //清屏 
    system("COLOR 8f");    //背景色提示 
    printf("------------------------------------------\n");
    printf("             花卉管理系统                 \n");
    printf("                                          \n");
    printf("    1.增加花卉信息    2.删除花卉信息      \n");
    printf("                                          \n");
    printf("    3.修改花卉信息    4.查找花卉信息      \n"); 
    printf("                                          \n"); 
    printf("    5.显示所有信息    6.排序              \n");
    printf("                                          \n"); 
    printf("                      0.退出管理系统      \n");
    printf("                                          \n");
    printf("------------------------------------------\n");
    printf("                                          \n");
    printf("    请输入菜单序号:");
}
 
//主函数 
int main(){
    system("cls");          // 清屏 
    Welcome();          //  欢迎页面 
    system("pause");    //暂停程序进程 
    LinkList L;    //结构体指针 
    ReadFile(&L);
    int choice = 1;     //全局变量 控制主函数内循环是否持续 
    while(choice){
        Menu();
        scanf("%d", &choice);
        switch(choice){
            case 1: Addflower(&L); break;              //添加函数 
            case 2: Deleteflower(&L); break;        //删除函数 
            case 3: Modifyflower(&L); break;        //修改函数 
            case 4: Searchflower(L); break;            //查找函数 
            case 5: Showflower(L); break;            //显示函数
            case 6: Sort(L);
            case 0: WriteFile(L); break;            //将链表保存到文件,同时关闭系统 
        }
    }
    return 0;
}
在C语言中,要打开一个文件,需要使用文件指针FILE *)来表示这个文件。打开文件的函数是fopen,其语法如下: ```c FILE *fopen(const char *filename, const char *mode); ``` 其中,filename是要打开的文件名,mode是打开文件的模式,有以下几种模式: - "r":只读模式,打开文件用于读取。 - "w":写入模式,打开文件用于写入。如果文件已存在,则会清空文件内容;如果文件不存在,则会创建一个新文件。 - "a":追加模式,打开文件用于写入。如果文件已存在,则会在文件末尾添加新内容;如果文件不存在,则会创建一个新文件。 - "rb"、"wb"、"ab":二进制模式下的读、写、追加模式。 打开文件成功后,fopen函数会返回一个指向表示该文件FILE结构体的指针。我们可以将这个指针保存下来,以便后续对文件进行读写操作。 例如,我们想打开一个名为test.txt的文件,并以只读模式读取其中的内容,可以使用以下代码: ```c FILE *fp; char ch; fp = fopen("test.txt", "r"); if (fp == NULL) { printf("打开文件失败!\n"); return 1; } while ((ch = fgetc(fp)) != EOF) { printf("%c", ch); } fclose(fp); ``` 在上述代码中,我们首先定义了一个文件指针fp,并使用fopen函数打开了一个名为test.txt的文件,模式为只读("r")。然后,我们判断文件是否成功打开,如果打开失败,输出错误信息并返回。如果打开成功,我们使用fgetc函数读取文件中的每个字符,并逐个输出,直到文件读取完毕。最后,我们使用fclose函数关闭文件
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值