您的位置:首页 > 编程语言 > C语言/C++

学习笔记8-C语言文件

2015-11-20 13:46 525 查看
文件

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

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

编码分类: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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: