P 161 项目-CRM(3)-主菜单 2023/3/23
一、显示主菜单
功能说明:用户打开软件,可以看到主菜单,输入5退出软件
思路分析:在customerManage.c中,编写一个函数mainMenu,显示菜单, 在main函数中调,用代码实现。
#include<stdio.h>
// 定义结构体数据类型
struct Customer{
int id; // 编号
int age; // 年龄
char name[10]; // 名字
char gender; // f 表示女,m表示男
char phone[16]; // 电话号码
char email[20]; // 邮箱
};
int loop = 1; // 控制是否退出主菜单
char key;
// 显示一个Customer变量的信息
// 这里我们接收的是结构体指针,目的是提高效率
void getCustomerInfo(struct Customer * customer){
printf("\n%d\t%s\t%s\t%d\t%c\t%s\t%s",(* customer).id,(* customer).gender,(* customer).name,(* customer).age,(* customer).phone,(* customer).email);
}
// 显示主菜单
void mainMenu(){
do {
printf("\n-----------------客户信息管理软件-----------------");
printf("\n 1 添 加 客 户");
printf("\n 2 修 改 客 户");
printf("\n 3 删 除 客 户");
printf("\n 4 客 户 列 表");
printf("\n 5 退 出");
printf("\n请选择(1-5):");
scanf("%c",&key);
getchar(); // 过滤回车
switch(key){
case '1':
printf("添加客户");
break;
case '2':
printf("修改客户");
break;
case '3':
printf("删除客户");
break;
case '4':
printf("客户列表");
break;
case '5':
printf("退出");
loop = 0;
break;
default:
printf("\n你的输入有误,请重新输入");
break;
}
}while(loop);
printf("\n你退出了客户管理系统");
getchar();
}
void main(){
mainMenu(); // 调用函数,显示菜单
}
P 162 项目-CRM(4)-显示客户 2023/3/24
一、显示客户
思路分析:
- 因为我们需要将多个客户保存起来,因此我们需要使用结构体数组-Customer 结构体数组。
- 编写一个函数listCutomers来显示客户信息。
- 在主菜单中调用listCustomers
#include<stdio.h>
#include<string.h>
// 定义结构体数据类型
struct Customer{
int id; // 编号
int age; // 年龄
char name[10]; // 名字
char gender; // f 表示女,m表示男
char phone[16]; // 电话号码
char email[20]; // 邮箱
};
int loop = 1; // 控制是否退出主菜单
char key;
int customerNum = 1; // 表示当前有多少个客户
// 定义客户结构体数组;数组显示多组数据
struct Customer customers[100];
// 显示一个Customer变量的信息
// 这里我们接收的是结构体指针,目的是提高效率
void getCustomerInfo(struct Customer * customer){
printf("\n%d\t%s\t%c\t%d\t%s\t%s",(* customer).id,(* customer).name,(* customer).gender,(* customer).age,(* customer).phone,(* customer).email);
}
// 显示客户信息列表
void listCustomer(){
int i = 0;
printf(" ---------------------------客户列表---------------------------");
printf("\n编号\t姓名\t性别\t年龄\t电话\t邮箱");
for(i = 0; i < customerNum; i++){ // 表示客户的编号,循环打印客户信息
getCustomerInfo(&customers[i]);
}
}
// 显示主菜单
void mainMenu(){
do {
printf("\n\n\n-----------------客户信息管理软件-----------------");
printf("\n 1 添 加 客 户");
printf("\n 2 修 改 客 户");
printf("\n 3 删 除 客 户");
printf("\n 4 客 户 列 表");
printf("\n 5 退 出");
printf("\n请选择(1-5):");
scanf("%c",&key);
getchar(); // 过滤回车
switch(key){
case '1':
printf("添加客户");
break;
case '2':
printf("修改客户");
break;
case '3':
printf("删除客户");
break;
case '4':
listCustomer();
break;
case '5':
printf("退出");
loop = 0;
break;
default:
printf("\n你的输入有误,请重新输入");
break;
}
}while(loop);
printf("\n你退出了客户管理系统");
getchar();
}
void main(){
// 为了测试显示客户信息,我们可以先初始化一个客户,后面通过界面进行添加
customers[0].id = 1;
customers[0].age = 10;
// 邮箱不可以直接像上面一样赋值
// 原因:此时数组是个指针,指针指向元素首地址,这样的话赋值相当于修改地址,不可以
// 需要用到拷贝的方法:如下
strcpy(customers[0].email,"yy@sohu.com");
customers[0].gender = 'f';
strcpy(customers[0].name,"zs");
strcpy(customers[0].phone,"110");
mainMenu(); // 调用函数,显示菜单
}
P 163 项目-CRM(5)-添加客户 2023/3/24
一、添加客户
功能说明:添加客户
思路分析:
- 编写一个add函数,在该函数中完成添加客户的功能。
- 在mainMenu调用即可
// 添加客户
void add(){
customers[customerNum].id = customerNum + 1; // 编号按照自增规则
// 因为这里下标为0表示的是第一个人,下标为2表示的是第二个人,所以要这么写
printf("\n---------------------添加客户---------------------");
printf("\n姓名:"); // 一定要过滤回车,要不然就会被下面拿到回车
scanf("%s",customers[customerNum].name);
getchar();
printf("\n性别:");
scanf("%c",&customers[customerNum].gender);
getchar();
printf("\n年龄:");
scanf("%d",&customers[customerNum].age);
getchar();
printf("\n电话:");
scanf("%s",customers[customerNum].phone);
getchar();
printf("\n邮箱:");
scanf("%s",customers[customerNum].email);
getchar();
printf("---------------------添加完成---------------------");
customerNum++; // 这里必须,自增;否则会将上一个信息覆盖掉
}
case '4':
listCustomer();
P 164 项目-CRM(6)-删除客户 2023/3/24
一、删除客户
功能说明:
思路分析:
- 先编写一个函数findindex,根据用户输入的id去查找,该id是否存在customer结构体数组中,如果存在,就返回该id 对应的index,因为id和index不是对应关系;如果id存在则返回对应的index,否则返回-1。
- 编写一个函数del,该函数根据接收的index来判断是否可以删除;如果接收到的index是-1,就不删除,否则就删除该index对应的客户。
- 编写delVIew函数,让用户可以输入要删除的id,并且mainMenu函数中调用。
#include<stdio.h>
#include<string.h>
// 定义结构体数据类型
struct Customer{
int id; // 编号
int age; // 年龄
char name[10]; // 名字
char gender; // f 表示女,m表示男
char phone[16]; // 电话号码
char email[20]; // 邮箱
};
int loop = 1; // 控制是否退出主菜单
char key;
int customerNum = 1; // 表示当前有多少个客户
// 定义客户结构体数组;数组显示多组数据
struct Customer customers[100];
// 显示一个Customer变量的信息
// 这里我们接收的是结构体指针,目的是提高效率
void getCustomerInfo(struct Customer * customer){
printf("\n%d\t%s\t%c\t%d\t%s\t%s",(* customer).id,(* customer).name,(* customer).gender,(* customer).age,(* customer).phone,(* customer).email);
}
// 添加客户
void add(){
customers[customerNum].id = customerNum + 1; // 编号按照自增规则
// 因为这里下标为0表示的是第一个人,下标为2表示的是第二个人,所以要这么写
printf("\n---------------------添加客户---------------------");
printf("\n姓名:"); // 一定要过滤回车,要不然就会被下面拿到回车
scanf("%s",customers[customerNum].name);
getchar();
printf("\n性别:");
scanf("%c",&customers[customerNum].gender);
getchar();
printf("\n年龄:");
scanf("%d",&customers[customerNum].age);
getchar();
printf("\n电话:");
scanf("%s",customers[customerNum].phone);
getchar();
printf("\n邮箱:");
scanf("%s",customers[customerNum].email);
getchar();
printf("---------------------添加完成---------------------");
customerNum++; // 这里必须,自增;否则会将上一个信息覆盖掉
}
// 根据输入的id,返回index,如果没有就返回-1。
int findIndex(int id){
int index = -1;
int i;
for(i = 0; i < customerNum; i++){
if(customers[i].id == id){ // 等于,就相当于找到了
index = i;
}
}
return index;
}
// 说明:
// 1.返回int,如果1就说明删除成功了
// 2.返回0,表示删除失败
// 3.接受的是要删除的客户id
int del(int id){ // 形参是要删除的id
int index = findIndex(id);
int i;
if(index == -1){ // 说明该id没有对应的客户
return 0; // 表示删除失败
}else{
// 说明有对应的客户,就要删除,删除的本质就是将编号为id的这个客户移除
// 1.从index + 1位置开始,整体前移
for(i = index + 1; i < customerNum; i++){
customers[i-1] = customers[i]; // 这里就是通过整体前移
customers[i-1].id--;
// 假如有5个客户要移除3,则经过函数findIndex得index=2,
}
// 2. customerNum - 1
customerNum--;
return 1; // 1 表示删除成功
}
}
// 显示删除客户的界面,然后调用
void delView(){
int id = 0;
char choice = ' ';
printf("\n---------------------删除客户---------------------");
printf("\n请选择待删除客户编号(-1退出):");
scanf("%d",&id);
getchar();
if(id == -1){
printf("\n删除未完成---------------------");
return;
}
printf("\n确认是否删除(Y/N):");
scanf("%c",&choice);
getchar();
if(choice == 'Y' || 'y'){
if(del(id) == 0){
printf("\n---------------------删除失败,因为id不存在---------------------");
}else{
printf("\n---------------------删除成功!---------------------");
}
}
}
// 显示客户信息列表
void listCustomer(){
int i = 0;
printf(" ---------------------------客户列表---------------------------");
printf("\n编号\t姓名\t性别\t年龄\t电话\t邮箱");
for(i = 0; i < customerNum; i++){ // 表示客户的编号,循环打印客户信息
getCustomerInfo(&customers[i]);
}
}
// 显示主菜单
void mainMenu(){
do {
printf("\n\n\n-----------------客户信息管理软件-----------------");
printf("\n 1 添 加 客 户");
printf("\n 2 修 改 客 户");
printf("\n 3 删 除 客 户");
printf("\n 4 客 户 列 表");
printf("\n 5 退 出");
printf("\n请选择(1-5):");
scanf("%c",&key);
getchar(); // 过滤回车
switch(key){
case '1':
add();
break;
case '2':
printf("修改客户");
break;
case '3':
delView();
break;
case '4':
listCustomer();
break;
case '5':
printf("退出");
loop = 0;
break;
default:
printf("\n你的输入有误,请重新输入");
break;
}
}while(loop);
printf("\n你退出了客户管理系统");
getchar();
}
void main(){
// 为了测试显示客户信息,我们可以先初始化一个客户,后面通过界面进行添加
customers[0].id = 1;
customers[0].age = 10;
// 邮箱不可以直接像上面一样赋值
// 原因:此时数组是个指针,指针指向元素首地址,这样的话赋值相当于修改地址,不可以
// 需要用到拷贝的方法:如下
strcpy(customers[0].email,"yy@sohu.com");
customers[0].gender = 'f';
strcpy(customers[0].name,"zs");
strcpy(customers[0].phone,"110");
mainMenu(); // 调用函数,显示菜单
}
二、简单分布图
P 165 项目-CRM(7)-功能完善 2023/3/24
一、完善退出确认功能
功能说明:要求用户在退出时提示 " 确认是否退出(Y/N):",用户必须输入Y/N, 否则循环提示。
思路分析:
- 使用do-while循环,提示用户输入Y/N,户必须输入Y/N, 否则循环提示。
- 需要在增加一个全局变量choice,表示用户的选择。
char choice = ' ' ; // 表示退出选择Y/N
case '5':
do{
printf("确认是否退出(Y/N):");
scanf("%c",&choice);
getchar();
}while(choice != 'Y'&& choice != 'N'); // 如果输入的不是Y,并且不是N
// 退出while循环后一定输出的是Y或者N
if(choice== 'Y' || choice== 'y' ){
loop = 0;
} // 如果输入的是N,不做处理,继续显示菜单
break;
default:
printf("\n你的输入有误,请重新输入");
break;
}
}while(loop);
printf("\n你退出了客户管理系统");
二、完成修改客户的功能
思路分析:修改客户时,需要先查找该用户,如果用户不存在,就需要提示并结束修改,如果找到用户,就显示该用户信息,然后输入新的信息,id不能修改!
#include<stdio.h>
#include<string.h>
// 定义结构体数据类型
struct Customer{
int id; // 编号
int age; // 年龄
char name[10]; // 名字
char gender; // f 表示女,m表示男
char phone[16]; // 电话号码
char email[20]; // 邮箱
};
int loop = 1; // 控制是否退出主菜单
char key;
int customerNum = 1; // 表示当前有多少个客户
char choice = ' ' ; // 表示退出选择Y/N
// 定义客户结构体数组;数组显示多组数据
struct Customer customers[100];
// 显示一个Customer变量的信息
// 这里我们接收的是结构体指针,目的是提高效率
void getCustomerInfo(struct Customer * customer){
printf("\n%d\t%s\t%c\t%d\t%s\t%s",(* customer).id,(* customer).name,(* customer).gender,(* customer).age,(* customer).phone,(* customer).email);
}
// 添加客户
void add(){
customers[customerNum].id = customerNum + 1; // 编号按照自增规则
// 因为这里下标为0表示的是第一个人,下标为2表示的是第二个人,所以要这么写
printf("\n---------------------添加客户---------------------");
printf("\n姓名:"); // 一定要过滤回车,要不然就会被下面拿到回车
scanf("%s",customers[customerNum].name);
getchar();
printf("\n性别:");
scanf("%c",&customers[customerNum].gender);
getchar();
printf("\n年龄:");
scanf("%d",&customers[customerNum].age);
getchar();
printf("\n电话:");
scanf("%s",customers[customerNum].phone);
getchar();
printf("\n邮箱:");
scanf("%s",customers[customerNum].email);
getchar();
printf("---------------------添加完成---------------------");
customerNum++; // 这里必须,自增;否则会将上一个信息覆盖掉
}
// 根据输入的id,返回index,如果没有就返回-1。
int findIndex(int id){
int index = -1;
int i;
for(i = 0; i < customerNum; i++){
if(customers[i].id == id){ // 等于,就相当于找到了
index = i;
}
}
return index;
}
// 说明:
// 1.返回int,如果1就说明删除成功了
// 2.返回0,表示删除失败
// 3.接受的是要删除的客户id
int del(int id){ // 形参是要删除的id
int index = findIndex(id);
int i;
if(index == -1){ // 说明该id没有对应的客户
return 0; // 表示删除失败
}else{
// 说明有对应的客户,就要删除,删除的本质就是将编号为id的这个客户移除
// 1.从index + 1位置开始,整体前移
for(i = index + 1; i < customerNum; i++){
customers[i-1] = customers[i]; // 这里就是通过整体前移
customers[i-1].id--;
// 假如有5个客户要移除3,则经过函数findIndex得index=2,
}
// 2. customerNum - 1
customerNum--;
return 1; // 1 表示删除成功
}
}
// 显示删除客户的界面,然后调用
void delView(){
int id = 0;
char choice = ' ';
printf("\n---------------------删除客户---------------------");
printf("\n请选择待删除客户编号(-1退出):");
scanf("%d",&id);
getchar();
if(id == -1){
printf("\n删除未完成---------------------");
return;
}
printf("\n确认是否删除(Y/N):");
scanf("%c",&choice);
getchar();
if(choice == 'Y' || 'y'){
if(del(id) == 0){
printf("\n---------------------删除失败,因为id不存在---------------------");
}else{
printf("\n---------------------删除成功!---------------------");
}
}
}
// 显示修改客户函数
int update(int id){
char key= ' ' ;
int index = findIndex(id);
if(index == -1){ // 说明该id没有对应的客户
return -1; // 表示修改失败
}else{
printf("\n1.姓名、2.姓别、3.年龄、4.电话、5.邮箱");
printf("\n请选择需要修改信息的编号:");
scanf("%c",&key);
switch(key){
// 这里会返回下标
case '1':
printf("\n姓名(原:%s):",customers[index].name);
scanf("%s",customers[index].name);
getchar();
break;
case '2':
printf("\n姓别(原:%c):",customers[index].gender);
scanf("%c",&customers[index].gender);
getchar();
break;
case '3':
printf("\n年龄(原:%d):",customers[index].age);
scanf("%d",&customers[index].age);
getchar();
break;
case '4':
printf("\n电话(原:%s):",customers[index].phone);
scanf("%s",customers[index].phone);
getchar();
break;
case '5':
printf("\n邮箱(原:%s):",customers[index].email);
scanf("%s",customers[index].email);
getchar();
break;
default:
printf("\n你输入的有误");
break;
}
}
}
// 修改客户界面
void updateView(){
int num = 0;
int back = 0;
printf("\n请选择待修改客户编号(-1退出):");
scanf("%d",&num);
getchar();
if(num == -1){
return ;
}else{
back = update(num);
if(back == -1 ){
printf("\n---------------------修改失败,客户id不存在---------------------");
}else{
printf("\n---------------------修改成功---------------------");
}
}
}
// 显示客户信息列表
void listCustomer(){
int i = 0;
printf(" ---------------------------客户列表---------------------------");
printf("\n编号\t姓名\t性别\t年龄\t电话\t邮箱");
for(i = 0; i < customerNum; i++){ // 表示客户的编号,循环打印客户信息
getCustomerInfo(&customers[i]);
}
}
// 显示主菜单
void mainMenu(){
do {
printf("\n\n\n-----------------客户信息管理软件-----------------");
printf("\n 1 添 加 客 户");
printf("\n 2 修 改 客 户");
printf("\n 3 删 除 客 户");
printf("\n 4 客 户 列 表");
printf("\n 5 退 出");
printf("\n请选择(1-5):");
scanf("%c",&key);
getchar(); // 过滤回车
switch(key){
case '1':
add();
break;
case '2':
updateView();
break;
case '3':
delView();
break;
case '4':
listCustomer();
break;
case '5':
do{
printf("确认是否退出(Y/N):");
scanf("%c",&choice);
getchar();
}while(choice != 'Y'&& choice != 'N'); // 如果输入的不是Y,并且不是N
// 退出while循环后一定输出的是Y或者N
if(choice== 'Y' || choice== 'y' ){
loop = 0;
} // 如果输入的是N,不做处理,继续显示菜单
break;
default:
printf("\n你的输入有误,请重新输入");
break;
}
}while(loop);
printf("\n你退出了客户管理系统");
getchar();
}
void main(){
// 为了测试显示客户信息,我们可以先初始化一个客户,后面通过界面进行添加
customers[0].id = 1;
customers[0].age = 10;
// 邮箱不可以直接像上面一样赋值
// 原因:此时数组是个指针,指针指向元素首地址,这样的话赋值相当于修改地址,不可以
// 需要用到拷贝的方法:如下
strcpy(customers[0].email,"yy@sohu.com");
customers[0].gender = 'f';
strcpy(customers[0].name,"zs");
strcpy(customers[0].phone,"110");
mainMenu(); // 调用函数,显示菜单
}
P 166 文件基本介绍 2023/3/24
一、基本介绍
介绍:文件,对我们并不陌生,文件是数据源(保存数据的地方)的一种,比如大家经常使用的word文档,txt文件,excel文件…都是文件。文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保持视频,声音…
二、流
文件在程序中是以流的形式来操作的。
**流:数据在数据源(文件)和程序(内存)**之间经历的路径
**输入流:**数据从数据源(文件)到程序(内存)的路径
**输出流:**数据从程序(内存)到数据源(文件)的路径
P167 C标准文件(输入输出) 2023/3/24
一、输入输出
- 当我们提到输入时,这意味着要向程序写入一些数据。输入可以是以文件的形式或从命令行中进行。C 语言提供了一系列内置的函数来读取给定的输入,并根据需要写入到程序中。
- 当我们提到输出时,这意味着要在屏幕上、打印机上或任意文件中显示一些数据。C 语言提供了一系列内置的函数来输出数据到计算机屏幕上和保存数据到文本文件或二进制文件(图片、声音、视频)中。
二、标准文件
- C 语言把所有的设备都当作文件。所以设备(比如显示器)被处理的方式与文件相同。以下三个文件会在程序执行时自动打开,以便访问键盘和屏幕。
-
文件指针是访问文件的方式,我们会讲解如何从屏幕读取值以及如何把结果输出到屏幕上。
-
C 语言中的 I/O (输入/输出) 通常使用 printf() 和 scanf() 两个函数。scanf() 函数用于从标准输入(键盘)读取并格式化, printf() 函数发送格式化输出到标准输出(屏幕)。
-
案例演示:
#include <stdio.h> // 执行 printf() 函数需要该库
int main()
{
printf("hello"); //显示引号中的内容
return 0;
}
P 168 文件读写三组函数 2023/3/25
一、getchar() & putchar() 函数
- int getchar(void) 函数从屏幕读取下一个可用的字符,并把它返回为一个整数。这个函数在同一个时间内只会读取一个单一的字符。您可以在循环内使用这个方法,以便从屏幕上读取多个字符。
- int putchar(int c) 函数把字符输出到屏幕上,并返回相同的字符。这个函数在同一个时间内只会输出一个单一的字符。您可以在循环内使用这个方法,以便在屏幕上输出多个字符。
- 应用实例:程序会读取一个单一的字符:
#include <stdio.h>
int main( )
{
int c;
printf( "Enter a value :");
c = getchar( ); // 读取一个char,返回一个int
printf( "\nYou entered: ");
putchar( c ); // 可以在屏幕上显示
printf( "\n");
getchar(); // 过滤回车
getchar(); // 暂停
return 0;
}
二、gets() & puts() 函数
char *gets(char *s)
函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。
- gets函数类似于scanf函数,用于读取标准输入。
- 前面我们已经知道scanf函数在读取字符串时遇到空格就认为读取结束,所以当输入的字符串存在空格时,我们需要使用gets函数进行读取。
- gets函数从STDIN(标准输入)读取字符并把它们加载到str(字符串)中,直到遇到换行符(\n)。
- 我们输入"how are you",共11个字符,可以看到gets会读取空格,同时可以看到我们并未给数组进行初始化赋值,但是最后有’\0’,这是因为gets遇到\n后,不会存储\n,而是将其翻译为空字符’\0’。
int puts(const char *s)
函数把字符串 s 和一个尾随的换行符写入到 stdout。
- 函数puts把str(字符串)写入STDOU(标准输出)。
- puts会将数组c中存储的
"how are you"
字符串打印到屏幕上,同时打印换行,相对于printf函数,puts只能用于输出字符串,同时多打印一个换行符,等价于printf(%s\n",c)
- 应用实例: 程序读取一整行直到该行结束。
#include <stdio.h>
int main( )
{
char str[100]; // 字符数组
printf( "输入字符串:");
gets( str );
printf( "\n你刚才输入的字符串是: ");
puts( str ); // 把刚刚接收到的字符串返回回来显示一遍
getchar();
return 0;
}
三、scanf() 和 printf() 函数
int scanf(const char *format, ...)
函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入。int printf(const char *format, ...)
函数把输出写入到标准输出流 stdout ,并根据提供的格式产生输出。- format 可以是一个简单的常量字符串,但是您可以分别指定 %s、%d、%c、%f 等来输出或读取字符串、整数、字符或浮点数。还有许多其他可用的格式选项,可以根据需要使用。如需了解完整的细节,可以查看这些函数的参考手册。现在让我们通过下面这个简单的实例来加深理解。
- 应用实例:您输入一个文本并按下回车键时,程序读取输入, 但是要求格式要匹配。
#include <stdio.h>
int main( ) {
char str[100];
int i;
printf( "Enter a value :");
scanf("%s %d", str, &i);
printf( "\nYou entered: %s %d ", str, i);
printf("\n");
getchar();
getchar();
return 0;
}
P 169 fopen和fclose及模式 2023/3/25
一、C文件读写
- 讲解了 C 语言处理的标准输入和输出设备。我们将介绍 如何创建、打开、关闭文本文件或二进制文件。
- 一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节。C 语言不仅提供了访问顶层的函数,也提供了底层(OS)调用来处理存储设备上的文件。本章将讲解文件管理的重要调用:
二、打开文件 fopen
-
使用 fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象,类型 FILE 包含了所有用来控制流的必要的信息。下面是这个函数
调用的原型:
FILE *fopen( const char * filename, const char * mode );
就是打开文件相应的指针。- 说明:在这里,filename 是字符串,用来命名文件,访问模式 mode 的值可以是下列值中的一个。
- 如果处理的是二进制文件(图片,视频…),则需使用下面的访问模式:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
模式 | 描述 |
---|---|
r | 打开一个已有的文本文件,允许读取文件。 |
w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。 在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为 零长度,重新写入!!!。 |
a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新 文件。在这里,您的程序会在已有的文件内容中追加内容。 |
r+ | 打开一个文本文件,允许读写文件。(文件会被截取为0长度) |
w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长 度,如果文件不存在,则会创建一个新文件。 |
a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。 读取会从文件的开头开始,写入则只能是追加模式。 |
三、关闭文件 fclose
关闭文件,使用 fclose( ) 函数。函数的原型如下:int fclose( FILE *fp );
- 如果成功关闭文件,fclose( ) 函数返回零,如果关闭文件时发生错误,函数返回 EOF。这个函数实际上,会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。EOF 是一个定义在头文件 stdio.h 中的常量。
- C 标准库提供了各种函数来按字符或者以固定长度字符串的形式读写文件。
- 使用完文件后(读,写),一定要将该文件关闭。
P 170 写文件和注意事项 2023/3/25
一、写入文件 fputs
下面是把字符写入到流中的函数:int fputc( int c, FILE \*fp );
- 说明:函数 fputc() 把参数 c 的字符值写入到 fp 所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回 EOF。您可以使用下面的函数来把一个以 null 结尾的字符串写入到流中:
int fputs( const char *s, FILE *fp );
#include<stdio.h>
void main(){
// 创建文件指针
FILE *fp = NULL;
// 打开改文件
fp = fopen("e:/ctest.txt","r+"); // w+模式是,文件会被阶段为0长度
// 将内容写入到文件中
fprintf(fp,"你好 北京~~\n");
fputs("你好 上海~~\n",fp);
// 关闭文件!!! 如果不关闭文件,将不会保存到我们的文件中
fclose(fp);
printf("创建,写入信息完成");
getchar();
}
P 171 读文件和注意事项 2023/3/25
一、读取文件 fgets
下面是从文件读取单个字符的函数:int fgetc( FILE * fp );
- 说明:fgetc() 函数从 fp 所指向的输入文件中读取一个字符。返回值是读取的字符,如果发生错误则返回 EOF。
- 下面的函数从流中读取一个字符串:
char *fgets( char *buf, int n, FILE *fp );
- 说明:函数 fgets() 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串。如果这个函数在读取最后一个字符之前就遇到一个换行符 ‘\n’ 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。
- 也可以使用 int fscanf(FILE *fp, const char *format, …) 函数来从文件中读取字符串,但是在遇到第一个空格字符时,它会停止读取。
#include<stdio.h>
void main(){
// 创建一个文件指针
FILE *fp = NULL;
// 定义一个缓冲区
char buff[1024];
// 打开文件
fp = fopen("e:/ctest100.txt","r");
// 方法1:
//fscanf(fp,"%s",buff); // 将fp所指向的文件里面读一行到buff里面去
输出
//printf("%s\n",buff);
// 方法2:读取整个文件
while(fgets(buff,1024,fp)!=NULL){ // 一行读取1024
// 读取整个文件,使用while循环,读取到空的基结束
printf("%s",buff);
}
fclose(fp); // 关闭文件
getchar();
}