Skip to content

Latest commit

 

History

History
906 lines (663 loc) · 17.9 KB

2022-1-9 输入-输出流: 223818.md

File metadata and controls

906 lines (663 loc) · 17.9 KB

输入-输出流:

[TOC]

ios::in 读文件
ios::out 为写文件而打开文件
ios::ate 初始位置:文件尾
ios::app 追加方式写文件
ios::trunc 如果文件存在先删除,再创建
ios::binary 二进制方式

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️

1. 写文件

o 首先要使用头文件

** **#include<fstream>**

  • 创建流对象

    ofstream ofs;

  • 指定打开方式 **--可以写绝对路径或者相对路径

    ofs.open("test.txt",ios::out);

  • 写内容

    ofs<<"姓名:"<<endl;

  • 关闭文件

    ofs.close();

2. 读文件

o 创建流对象**

ifstream ifs;**

  • 打开文件,判断文件是否打开成功 ifs.open("文件路径",打开方式);
if(!ifs.is_open())

{

cout<<"文件打开失败"<<endl;

return;

}
  • 读数据

    ​ 四种读取方式

第一种:
char buf[1024] = { 0 };

//定义字符数组

while(ifs >> buf)

{

cout << buf <<endl;

}
第二种:
char buf[1024] = { 0 };

//getline获取,sizeof统计字符长度

while(ifs.getline(buf,sizeof(buf)))

{

cout << buf <<endl;

}
第三种
//使用string --需要包含string头文件

while ( getline( ifs,buf ))

{

cout<< buf <<endl;

}
第四种:不推荐 --依次读取字符
char c;

while (( c=ifs.get())!=EOF)

{ //eof是文件尾部的标志

cout<<c;

}
  • 关闭文件

    ifs.close();

总结:
\1.  读文件可以使用ifstream,或者fstream类

\2.  利用is_open函数判断文件是否打开成功

\3.   close关闭文件
代码:
#include<iostream>

#include<fstream>  //包含头文件

using namespace std;

//文本文件 读文件

void test01()

{
    //创建流对象
    ifstream ifs;
    
 	//打开文件
    ifs.open("/c/cpp/tar.cpp",ios::in);

    if(!ifs.is_open())      
    {
        cout<<"文件打开失败"<<endl;
        return ;
    }

    char buf[1024] = { 0 };
    //定义字符数组
    while(ifs >> buf)
    {
        cout << buf <<endl;
   }

    ifs.close(); //关闭文件
}

int main()

{

    test01();
    return 0;

}

 

3 . 以二进制形式对文件进行读取操作

代码:
#include<fstream>

#include<iostream>

using namespace std;
//二进制写文件
class Person
{
public:
  char m_Name[64];
  int m_Age;
};

 void test01()
{
  //创建流对象
 ofstream ofs; 
     
  //打开文件  //用二进制打开方式要指定为 ios::binary
  ofs.open("/c/cpp/tar.cpp",ios::out | ios::binary);
    
  //写文件
  Person p ={"张三",18};
  ofs.write((const char *)&p,sizeop(Person));

//由于&p取地址是person类型,所以要强制转换为char

  //关闭文件
  ofs.close();

}

int main()
{
  test01();
  return 0;
}

😊求赞!

查看文件:

img

由此可见是二进制形式,那么如何把文件读取回来呢?

4 . 文件读取:

读文件用read

\1. 函数原型: **istream& read(char *buffer,int len);**

\2. 参数解释:字符指针buffer指向内存中一段存储空间。len是读取的字节数

代码:
include<fstream>

include<iostream>

using namespace std;


//读取二进制文件

class Person

{

public:
  char m_Name[64];  //属性姓名
  int m_Age;    //属性年龄
};

 void test01()
{
  //创建流对象
  ifstream ifs;       //注意读文件和写文件流对象区别

  //打开文件
  ifs.open("/c/cpp/tar.cpp",ios::in | ios::binary);
	
  //判断文件是否读入成功  --使用前面讲的方法
  if (!ifs.is_open())
  {
      cout << "文件打开失败"<<endl;
      return ;   //不返回
  }

//

  //读文件  --四种方法选择一种
    Person p;
    ifs.read((char *)&p,sizeof(Person));
    cout <<"姓名:"<<p.m_Name<<"年龄:"<<p.m_Age<<endl;
    //由于&p取地址是person类型,所以要强制转换为char
    //关闭文件
    ifs.close();

}

 

int main()
{
  test01();
  return 0;
}

5 . 加密解密(c语言实现)

代码:

void myEncodeAnDecode(char prePath[], char resultPath[], int password) {
    FILE * normal_fp = fopen(prePath, "rb");
    FILE * encode_fp = fopen(resultPath, "wb");
    int ch;
    while ((ch = fgetc(normal_fp)) != EOF){
        fputc(ch ^ password, encode_fp);
    }
    fclose(normal_fp);
    fclose(encode_fp);
}
int main() {
    char * oriPath = "D:\\picLibrary\\xiaoHuangTu.png";
    //原文件,加密后可删除掉,防止别人查看
    
    char * showOthersPath = "D:\\picLibrary\\xiaoHuangEncode.png";
    //存放加密的文件,给别人看,别人也看不了的文件
    
    char * newPath = "D:\\picLibrary\\xiaoHuangDecode.png";
    //将加密的文件解密出来的文件,可以自己偷偷的查看

    //加密
    myEncodeAnDecode(oriPath, showOthersPath, 100);//密码随便搞个100
    //解密
    myEncodeAnDecode(showOthersPath, newPath, 100);
    system("pause");
    return 0;

}

5 . 加密解密


基于前面的扩展,使用通讯录管理系统实现联系人的读取、写入

通讯录项目:

需求分析:

问题描述

编写一个简单的通讯录管理程序。通讯录记录有姓名,地址**(省、市()、街道)****,电话号码,邮政编码等四项。**

基本要求

程序应提供的基本管理功能有:

1) 添加:即增加一个人的记录到通信录中

2) 显示:即在屏幕上显示所有通信录中的人员信息,应能分屏显示。

3) 存储:即将通讯录信息保存在一个文件中。

4) 装入:即将文件中的信息读入程序。

5) 查询:可根据姓名查找某人的相关信息,若找到显示其姓名、地址、电话号码和邮政编码。

6) 修改:可修改一个人的除姓名外其它信息。

测试数据

程序应输入不少于10个人员的通讯录信息,应考虑到人员可以同名的情况。

实现提示

程序可用一个动态数组来管理人员信息,每个人员的姓名,地址,电话号码和邮政编码用一个类Cperson来实现,用文件实现对数据的存取。

代码:
//封装函数显示该界面 如 void showMenu()
//在main函数中调用封装好的函数

#include<stdio.h>
#include<iostream>
#include<stdlib.h>   
#include<string>

#include<fstream>  //包含文件头文件
#define FILENAME "/c/cpp/empfile.txt"  //文件路径
#define MAX 1000    //定义通讯录的最大用户数量 

//保存文件
void sava();

//读取文件
//判断文件受否为空的
bool m_FileIsEmpty;

using namespace std;

struct Person
 //设计联系人结构体
{
	//姓名
	string m_Name;
	//性别 1:男 2:女
	int m_Sex;
	//年龄
	int m_Age;
	//电话
	string m_Phone;
	//住址
	string m_Addr;
	//邮政编码
	string m_Pos; 
};

//设计通讯录结构体
struct Addressbooks
{
	//通讯录中保存的联系人的数组
	struct Person personArray[MAX];

	//通讯录中当前记录联系人的个数
	int m_Size;
};

//提前声明菜单函数,用背景函数调用菜单函数
void showMenu();

class Color{      //设置通讯录的背景颜色类型 ---将其封装成类	
public:
	void setColor()       //定义颜色函数 
	{
		int c;
		printf("\t\t以下为可选择背景色及字体颜色:\n\n");
		printf("\t\t\t1.系统默认\n"); 
		printf("\t\t\t2.白底黑字\n"); 
		printf("\t\t\t3.灰底黑字\n"); 
		printf("\t\t\t4.蓝底黑字\n\n");
		printf("\t\t\t0.不选跳出\n\n");
		printf("\t\t请输入您选择的序号:"); 
		scanf("%d",&c);
		switch(c)
		{
			case 1:break;
			case 2:system("color F0"); break;
			case 3:system("color 70"); break;
			case 4:system("color B0"); break;
			case 0:break;
			default:printf("\n\t\t输入错误,请您重新输入!\n\n");
			setColor();
		}
		system("cls");
		} 
	
};

//菜单界面
void showMenu()
{
	cout << "***************************" << endl;
	cout << "*****  1、添加联系人  *****" << endl;
	cout << "*****  2、显示联系人  *****" << endl;
	cout << "*****  3、删除联系人  *****" << endl;
	cout << "*****  4、查找联系人  *****" << endl;
	cout << "*****  5、修改联系人  *****" << endl;
	cout << "*****  6、清空联系人  *****" << endl;
	cout << "*****  0、退出通讯录  *****" << endl;
	cout << "*****  9、通讯录背景  *****" << endl; 
	cout << "***************************" << endl;
}



// 1、添加联系人
void addPerson(struct Addressbooks* abs)
{
	//判断通讯录是否已满
	if (abs->m_Size == MAX)
	{
		cout << "通讯录已满,无法继续添加!" << endl;
		return;
	}
	else
	{
		//添加具体联系人

		//姓名
		cout << "请输入姓名:" << endl;
		string name;
		cin >> name;
		abs->personArray[abs->m_Size].m_Name = name;

		//性别 1:男 2:女
		cout << "请输入性别:" << endl;
		cout << "1 --- 男" << endl;
		cout << "2 --- 女" << endl;
		int sex = 0;
		while (true)
		{
			cin >> sex;
			if (sex == 1 || sex == 2)
			{
				abs->personArray[abs->m_Size].m_Sex = sex;
				break;
			}
			else
			{
				cout << "输入有误,请重新输入!" << endl;
			}
		}
		
		//年龄
		cout << "请输入年龄:" << endl;
		int age = 0;
		cin >> age;
		abs->personArray[abs->m_Size].m_Age = age;
		
		//电话
		cout << "请输入联系电话:" << endl;
		string phone;
		cin >> phone;
		abs->personArray[abs->m_Size].m_Phone = phone;

		//住址
		cout << "请输入家庭住址:" << endl;
		string address;
		cin >> address;
		abs->personArray[abs->m_Size].m_Addr = address;

		//邮政编码 ----例如432000 
		cout << "请输入邮政编码,一共六位" << endl;
		string postal;       //邮政编码变量
		cin >> postal;
		abs->personArray[abs->m_Size].m_Pos = postal;
		

		//更新通讯录中的人数
		abs->m_Size++;

		cout << "添加成功!" << endl;

		system("pause"); // 按任意键继续

		system("cls"); // 清屏
	}
}

//2、显示所有联系人
void showPerson(struct Addressbooks* abs)
{
	cout<<"------------联系人列表----------------"<<endl;
	//判断通讯录中人数是否为零
	if (abs->m_Size == 0)
	{
		cout << "当前记录为空" << endl;
	}
	else
	{
		for (int i = 0; i < abs->m_Size; i++)
		{
			cout << "姓名:" << abs->personArray[i].m_Name <<"||"<<endl;
			cout << "性别:" << (abs->personArray[i].m_Sex == 1 ? "" : "") <<"||"<< endl; // 括号,提高三目运算符优先级
			cout << "年龄:" << abs->personArray[i].m_Age << "||"<<endl;
			cout << "电话:" << abs->personArray[i].m_Phone << "||"<<endl;
			cout << "住址:" << abs->personArray[i].m_Addr <<"||"<< endl;
			cout << "邮政编码 :" << abs->personArray[i].m_Pos <<"||"<<endl;     //显示邮政编码信息 
		}
	}
	cout<<"--------------------------------------"<<endl;
	system("pause"); // 按任意键继续
	system("cls"); // 清屏
}

//3、检测联系人是否存在,若存在,返回联系人所在数组中的下标,若不存在,返回-1
int isExist(struct Addressbooks* abs, string name)
{
	for (int i = 0; i < abs->m_Size; i++)
	{
		//找到了用户输入的姓名
		if (abs->personArray[i].m_Name == name)
		{
			return i;
		}
	}
	//遍历结束都没找到用户输入的姓名
	return -1;
}

//3、删除指定联系人
void deletePerson(struct Addressbooks* abs)
{
	cout << "请输入你要删除的联系人:" << endl;
	string name;
	cin >> name;
	int ret = isExist(abs, name); // 外层的的deletePerson中传入的abs已经是指针了,故此处的abs不需要取址!
	if (ret != -1)      //isExist用来检测联系人是否存在 
	{
		//找到此人,要进行删除操作
		for (int i = ret; i < abs->m_Size; i++) // 从ret开始前移
		{
			//数据前移
			abs->personArray[i].m_Name = abs->personArray[i + 1].m_Name;
		}
		abs->m_Size--; // 更新通讯录中的人员数
		cout << "删除成功!" << endl;
	}
	else
	{
		cout << "查无此人!" << endl;
	}
}

//4、查找指定联系人信息
void findPerson(struct Addressbooks* abs)
{
	cout << "请输入你要查找的联系人" << endl;
	string name;     //定义变量name
	cin >> name;

	//判断指定的联系人是否存在
	int ret = isExist(abs, name);
	if (ret != -1)
	{
		//找到了用户输入的姓名
			cout << "姓名:" << abs->personArray[ret].m_Name <<"||"<<endl;
			cout << "性别:" << (abs->personArray[ret].m_Sex == 1 ? "" : "") <<"||"<< endl; // 括号,提高三目运算符优先级
			cout << "年龄:" << abs->personArray[ret].m_Age << "||"<<endl;
			cout << "电话:" << abs->personArray[ret].m_Phone << "||"<<endl;
			cout << "住址:" << abs->personArray[ret].m_Addr <<"||"<< endl;
			cout << "邮政编码 :" << abs->personArray[ret].m_Pos <<"||"<<endl;     //显示邮政编码信息 
	}
	else
	{
		cout << "查无此人!" << endl;
	}
	system("pause");
	system("cls");
}

//5、修改指定联系人的信息
void modifyPerson(struct Addressbooks* abs)
{
	cout << "请输入要修改的联系人" << endl;
	string name;  
	cin >> name;

	int ret = isExist(abs, name);
	if (ret != -1)
	{
		//找到了指定的联系人

		//姓名
		cout << "请输入姓名:" << endl;
		string name;
		cin >> name;
		abs->personArray[ret].m_Name = name;

		//性别 1:男 2:女
		cout << "请输入性别:" << endl;
		cout << "1 --- 男" << endl;
		cout << "2 --- 女" << endl;
		int sex = 0;
		while (true)
		{
			cin >> sex;
			if (sex == 1 || sex == 2)
			{
				abs->personArray[ret].m_Sex = sex;
				break;
			}
			else
			{
				cout << "输入有误,请重新输入!" << endl;
			}
		}

		//年龄
		cout << "请输入年龄:" << endl;
		int age = 0;
		cin >> age;
		abs->personArray[ret].m_Age = age;

		//电话
		cout << "请输入联系电话:" << endl;
		string phone;
		cin >> phone;
		abs->personArray[ret].m_Phone = phone;

		//住址
		cout << "请输入家庭住址:" << endl;
		string address;
		cin >> address;
		abs->personArray[ret].m_Addr = address;
		
		//邮政编码的修改
		cout << "请输入新的邮政编码:" << endl;
		string postal;
		cin >> postal;
		abs -> personArray[ret].m_Pos = postal;
	 
		cout <<"--------------------------------"<<endl;
		cout << "修改成功!" << endl;
	}
	else
	{
		cout << "查无此人!" << endl;
	}
	system("pause");
	system("cls");
}

//6、清空所有联系人
void cleanPerson(struct Addressbooks* abs)
{
	abs->m_Size = 0; // 将当前记录的联系人数量置为0,做逻辑上的清空
	cout << "通讯录已清空" << endl;
	system("pause");
	system("cls");
}
/*
//通信录文件的读入与存取
 class File{
 	//文件封装类
	 public:
	 File *fp;   //定义文件指针 
	 int i,No;
	 float salary; 
	 //文件的打开
	 fp = fopen("data.csv","r");  //改用读取的形式"r"
	 if(fp==NULL)
	 {
	 	printf("打开成功!");
	 	exit(0);   //使用0形式退出,需要包含stdlib头文件 
	 } 
	 
	//从文件中读取联系人的基本信息,并且显示出来
	void Fileread()
	{
		for(i=0;i<5;i++)
		{
			fscanf(fp,"%d,%f",&No,&salary);//格式化输出fscanf
			printf("%d\t%.2f\n",no,salary); 
		}
		fclose(fp);
		return 0;	
	}
 };
*/

int main()
{
	//创建通讯录结构体变量
	struct Addressbooks abs;
	//初始化通讯录中当前的人员个数
	abs.m_Size = 0;

	int select = 0; // 创建用户选择输入的变量
	Color colA; 
	colA.setColor();      //调用颜色 
	while (true)
	{
		showMenu(); 
		//菜单调用

		cin >> select;

		switch (select)
		{
		case 1: // 1、添加联系人
			addPerson(&abs); // 利用地址传递可以修改实参
			break;

		case 2: // 2、显示联系人
			showPerson(&abs);
			break;

		case 3: // 3、删除联系人
		{
			deletePerson(&abs);
			system("pause");
			system("cls");
		}
			break;

		case 4: // 4、查找联系人
			findPerson(&abs);
			break;

		case 5: // 5、修改联系人
			modifyPerson(&abs);
			break;

		case 6: // 6、清空联系人
			cleanPerson(&abs);
			break;

		case 0: // 0、退出通讯录
			cout << "---欢迎下次使用---"<<'\t'<<"--good--bye--" << endl;
			system("pause"); // 按任意键继续
			return 0;
			break;
			
		case 9:  //9 、设置通讯录的背景  -- 使用C语言的函数,将其封装为类
			colA.setColor();
			break;

		default:
			break;
		}
	}
	system("pause");
	return 0;
}

职工管理系统:

需求分析:

公司员工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职工的职责,完成经理交付的任务。

经理职责:完成老板交付的任务,并且下发给员工

老板职责:管理公司所用事务

实现功能:
  • 退出管理程序
  • 增加职工信息: 实现批量添加,录入到文件中
  • 显示职工信息
  • 删除离职职工
  • 修改职工信息:
  • 查找职工信息: 按照职工编号查找
  • 按照编号排序: 排序方式由用户指定
  • 清空所有文档: 需要再次确认清空

#界面展示:

代码:

image-20211203233018659