7,文件的偏移操作
在文件程序中通常用ftell和rewind函数来进行偏移,其中,ftell返回与起始位置的偏移量,rewind返回文件的起始位置ftell和rewind函数的参数都为文件指针,都是直接返回偏移位置,具体说明和代码如下:
#include<stdio.h>
int main()
{
FILE* pa = fopen("E:\\text\\test3.txt", "r");//文件中是123456789abcdef长度为15
if (!pa)
{
puts("兔子");
exit(1);
}
fseek(pa, -1, SEEK_END);//文件最后一个元素
printf("%c\n", fgetc(pa));//fgetc()会得到此时指向位置的一个数据,并自动往下一个位置偏移
printf("%d\n", ftell(pa));//输出15
rewind(pa);//将文件指向数据的起始位置,即0
printf("%d",ftell(pa));
fclose(pa);
pa = NULL;
return 0;
}
8,文件的报错和判断
在进行文件的读取操作时,可能因某种原因导致失败,而通常用feof()函数来判断文件是否读取末尾才结束的,注意:feof()函数不能判断函数出错的情况,只能判断是否读取完毕,当读写的完毕时返回0,读写因某种原因而没有进行全的返回非0,因为在文件中,当读取完毕时文件末尾是EOF,数值为-1,与字符串结束标志'\0'一样,都是一种结束的标志。perror()用来错误报错的函数,每当发生错误时,在程序的内部中都会生成一种错误码,而perror()函数将其错误码提取出来显示。代码如下:
#include<stdio.h>
int main()
{
char c;
FILE* pa = fopen("E:\\text\\test1.txt", "r");//文件里面为987654321
if (!pa)
{
perror("兔子");//输出“兔子: No such file or directory”表示错误
exit(1);
}
while ((c = fgetc(pa)) != EOF)//从文件开始循环到文件结束
putchar(c);//putchar函数输出字符时不换行
//注意,不能用以下用法
/*while(fgetc(pa)!=EOF)
putchar(fgetc(pa));*/
//因为一遇到fgetc函数就会跳向下一个字符
if (ferror(pa))//若读写错误返回非零,读写正确返回0值
perror("\n错误");
if (feof(pa))//如果当前位置在文件结尾(即EOF)返回非零,否则返回0值
puts("\n成功");
return 0;
}
三,文件的程序实用
下面,我们用文件来实现通讯录的实现,在通讯录上增加两个函数,实现数据可以保存到文件,也可以从文件中加载数据。
函数一:添加一个函数,在退出通讯录的时候把信息到保存到文件中
函数二:添加一个函数,在通讯录打开的时候,可以把文件中的信息加载到通讯录中
我们用C++的来实现具体以下代码:
1,头文件的引用:
//下面为C++所提供的一系列头文件
#include<iostream>
#include<windows.h>
#include<cstring>
#include<cstdlib>
#include<cassert>
using namespace std;
//设置通讯录最大的容量,可根据情况进行修改
#define m 1000
//通讯录的菜单
void menu();
//增添人员
void addperson(struct add* a, int*);
//展示通讯录中的人员
void show(struct add* a);
//删除通讯录中的指定人员
void deleteperson(struct add* a);
//查找通讯录中的指定人
void found(struct add* a);
//修改指定人的消息
void fix(struct add* a);
//清空通讯录
void clean(struct add* a);
//用来查找指定人的序号
int foundperson(struct add* a, string);
//将程序保存到文件中
void savefile(struct add* a);
//将文件中的数据拿出,放到通讯录中
void loadfile(struct add* a);
2,功能程序的实现
#include"list.h"
struct person
{
string name;
int sex;
int age;
string phone;
string number;
string address;
};
struct add
{
struct person arr[m];
int size;
}a;
void menu()
{
cout << "*********************************" << endl;
cout << "****** 1,添加联系人 ******" << endl;
cout << "****** 2,显示联系人 ******" << endl;
cout << "****** 3,删除联系人 ******" << endl;
cout << "****** 4,查找联系人 ******" << endl;
cout << "****** 5,修改联系人 ******" << endl;
cout << "****** 6,清空联系人 ******" << endl;
cout << "****** 0,退出通讯录 ******" << endl;
cout << "*********************************" << endl;
}
void addperson(struct add* a, int* p)
{
if (a->size == m)
{
cout << "通讯录存放已满,无法添加" << endl;
return;
}
else
{
//姓名
cout << "请输入姓名: ";
cin >> a->arr[*p].name;
//性别
cout << "1,男\n" << "2,女" << endl;
while (true)
{
cout << "请选择性别: ";
int select;
cin >> select;
if (select == 1 || select == 2)
{
if (select == 1)
a->arr[*p].sex = 1;
else
a->arr[*p].sex = 2;
break;
}
else
cout << "输入错误,请重新输入" << endl;
}
//年龄
cout << "请输入年龄: ";
cin >> a->arr[*p].age;
//电话
cout << "请输入电话: ";
cin >> a->arr[*p].phone;
//身份证号
cout << "请输入身份证号: ";
cin >> a->arr[*p].number;
//地址
cout << "请输入家庭地址: ";
cin >> a->arr[*p].address;
}
system("pause");
system("cls");
}
void show(struct add* a)
{
if (a->size == 0)
cout << "当前没有任何记录" << endl;
else
{
cout << "此时通讯录中的记录的人员如下:" << endl;
for (int i = 0; i < a->size; i++)
{
cout << "姓名: " << a->arr[i].name << " ";
cout << "性别: " << (a->arr[i].sex == 1 ? "男" : "女") << " ";
cout << "年龄: " << a->arr[i].age << " ";
cout << "手机号: " << a->arr[i].phone << " ";
cout << "身份证号: " << a->arr[i].number << " ";
cout << "家庭地址: " << a->arr[i].address << endl;
}
}
system("pause");
system("cls");
}
int foundperson(add* a, string name1)
{
for (int i = 0; i < a->size; i++)
{
if (a->arr[i].name == name1)
{
return i;
}
}
return -1;
}
void deleteperson(add* a)
{
string name;
int number;
cout << "请输入要删除人员的姓名: ";
cin >> name;
number = foundperson(a, name);
if (number != -1)
{
for (int i = number; i < a->size; i++)
{
a->arr[i] = a->arr[i + 1];
}
a->size--;
cout << "删除成功" << endl;
}
else
{
cout << "没有此人" << endl;
}
system("pause");
system("cls");
}
void found(add* a)
{
int i;
string name;
cout << "请输入要查找人的姓名: ";
cin >> name;
i = foundperson(a, name);
if (i != -1)
{
cout << "姓名: " << a->arr[i].name << " ";
cout << "性别: " << (a->arr[i].sex == 1 ? "男" : "女") << " ";
cout << "年龄: " << a->arr[i].age << " ";
cout << "手机号: " << a->arr[i].phone << " ";
cout << "身份证号: " << a->arr[i].number << " ";
cout << "家庭地址: " << a->arr[i].address << endl;
}
else
{
cout << "没有此人" << endl;
}
system("pause");
system("cls");
}
void fix(add* a)
{
int number;
string name;
cout << "请输入即将要修改人的名字: ";
cin >> name;
number = foundperson(a, name);
if (number != -1)
{
cout << "请输入将要修改成员的信息" << endl;
addperson(a, &number);
show(a);
}
else
{
cout << "没有此人" << endl;
system("pause");
system("cls");
}
}
void clean(add* a)
{
a->size = 0;
cout << "通讯录已全部清空" << endl;
system("pause");
system("cls");
}
//文件函数,将数据保存到文件中,但是要注意的是,保存到文件中的数据不安全
void savefile(struct add* a)
{
int i = 0, j = 0;
FILE* pa = fopen("E:\\text\\test4.txt", "w");
if (!pa)
{
perror("error");
exit(0);
}
for (i = 0; i < a->size; i++)
{
fwrite(a->arr + i, sizeof(struct person), 1, pa);
}
fclose(pa);
pa = 0;
}
//将文件的数据放入通讯录中
void loadfile(struct add* a)
{
int i = 0;
struct add p;
FILE* pa = fopen("E:\\text\\test4.txt", "rb");
if (!pa)
{
perror("error");
exit(0);
}
while (fread(a->arr + a->size, sizeof(struct person), 1, pa))
{
a->size++;
}
fclose(pa);
pa = 0;
}
int main()
{
int select;
a.size = 0;
cout << "\t\t\t\t\t\t通讯录的制作" << endl;
//在打开通讯录时将文件中的信息加载到程序里面
loadfile(&a);
do
{
menu();
cin >> select;
switch (select)
{
case 0:
//加载文件,将通讯录放到指定文件中
savefile(&a);
cout << "您已退出系统平台" << endl;
break;
case 1:
cout << "您已进入“添加联系人”模式" << endl;
addperson(&a, &a.size);
a.size++;
break;
case 2:
cout << "您已进入“显示联系人”模式" << endl;
show(&a);
break;
case 3:
cout << "您已进入“删除联系人”模式" << endl;
deleteperson(&a);
break;
case 4:
cout << "您已进入“查找联系人”模式" << endl;
found(&a);
break;
case 5:
cout << "您已进入“修改联系人”模式" << endl;
fix(&a);
break;
case 6:
cout << "您已进入“清空联系人”模式" << endl;
clean(&a);
break;
default:cout << "输入错误,请重新输出" << endl;
}
} while (select);
return 0;
}