第三部分文件操作部分
一. c語言文件指針
- 定義
-
指向一個文件的指針變量
FILE *指針變量名; FILE *fp = NULL; 注意:FILE是一個結構體
-
- 文件的打開和關閉
-
文件的打開
建立文件的關聯關系,用文件指針指向某個具體的文件,文件打開需要使用 fopen fopen("文件名","打開方式"); 注意:fopen有返回值, 如果打開文件成功,返回文件的首地址 如果打開文件失敗,返回的是NULL 完整的打開文件的語句: FILE *fp = NULL; fp = fopen("a.txt","r"); //r 只讀 簡化: FILE *fp = fopen("a.txt","r");
-
文件的關閉
fclose(文件的指針); fclose(fp);
-
- 字符讀寫函數:fgetc和fputc
- fputc 函數的作用 向指定文件中寫入一個字符 ,fputc(字符常量或者是字符變量,文件指針);fputc函數有返回值,返回的時寫入的字符
- fgetc 函數的作用 從指定的文件中讀取一個字符,fgetc每次從文件中讀取一個字符
- 數據塊讀寫函數fread和write
-
fwrite 和 fread 是數據的寫入和讀取的函數,每次讀寫一塊數據,不是讀取字符個數 fwrite(buffer,size,count,fp);fread(buffer,size,count,fp);
//定義文件指針 FILE *fp = fopen("fwriteString.txt","w"); //判斷文件是否打開成功 if(fp!=NULL){ // fwrite(buffer,size,count,fp); char str[]="helloWorld!"; //使用fwrite 寫入一塊數據 fwrite(str,strlen(str),1,fp); printf("文件寫入成功!\n"); }
從文件中讀取結構體信息 fwrite(&stu[i],sizeof(struct Studnet),1,fp)
-
#include<stdio.h>
int main()
{
struct student{
char name[20];
char sex;
int age;
float score;
};
struct student stu[5]={{"zbz",'F',38,59.99f},{"sb",'F',48,59.99f},{"cgx",'F',18,59.99f},{"dlj",'M',8,59.99f},{"banzhang",'Y',18,99.99f}};
//寫入數據
FILE *fp = fopen("student.data","wb+");
if(fp!= NULL){
for(int i = 0 ; i < 5 ; i++){
fwrite(&stu[i],sizeof(struct student ),1,fp);
}
printf("文件寫入成功!\n\n\n");
// 文件指針拉回來
rewind(fp);
struct student stuArray[5];
printf("姓名\t\t性別\t\t年齡\t\t成績\n");
for(int i = 0 ; i < 5 ; i++){
fread(&stuArray[i],sizeof(struct student),1,fp);
printf("%s\t\t%c\t\t%d\t\t%.2f\n",stuArray[i].name,stuArray[i].sex,stuArray[i].age,stuArray[i].score);
}
}
return 0;
}
3. 格式化讀寫函數fscanf和fprintf
1. fscanf() 格式化的讀取,從文件中讀取
2. fprintf() 格式化的寫入,寫入到文件中
fscanf(fp,"%d:%f,%s\n%s",&productId,&productPrice,productTitle,productTitleImg);
fprintf(fp,"%d:%.2f,%s\n%s",productId,productPrice,productTitle,productTitleImg);
二實現通訊錄操作--代碼實現
#include<stdio.h>
#include<string.h>
//定義宏,聯系人數組的長度,姓名長度,電話號碼的長度
#define NAME_LEN 22
#define TELNUM_LEN 16
#define LEN 100
typedef struct{
char name[NAME_LEN];
char telNum[TELNUM_LEN];
} Person; //給結構體起一個別名
//定義聯系人數組,保存聯系人個數,文件的名稱
Person contacts[LEN];
int totalContactCount=0;
char *filePath="telbook.data";
//定義函數,并且聲明
void doAdd();
void doDelete();
void doUpdate();
void doList();
void doSearchByName();
void init();
void writeToFile();
int main()
{
init();
int flag = 1;//退出的標志
int num=0;
while(flag){
//編寫控制程序
printf("\n\n**************************\n");
printf("****** 歡迎使用通訊錄 ******\n");
printf("****** 1、添加聯系人 ******\n");
printf("****** 2、刪除聯系人 ******\n");
printf("****** 3、修改聯系人 ******\n");
printf("****** 4、查看所有聯系人 ****\n");
printf("****** 5、搜索聯系人 ******\n");
printf("****** 6、退出系統 ******\n");
printf("**************************\n\n");
printf("請輸入1-6之間的序號,選擇要執行的功能\n");
//接收用戶輸入的編號
scanf("%d",&num);
if(num<1||num>6){
printf("輸入錯誤!\n");
}else{
//根據不同的編號,執行不同的功能
switch(num){
case 1:
doAdd();
break;
case 2:
doDelete();
break;
case 3:
doUpdate();
break;
case 4:
doList();
break;
case 5:
doSearchByName();
break;
case 6:
printf("正在退出系統...\n");
printf("系統已經退出!\n");
//return 0;
flag = 0;
break;
default:
break;
}
}
}
return 0;
}
/**
* 添加聯系人
1) 提示用戶輸入聯系人信息
2)接收聯系人信息
3)提示輸入電話號碼信息
4)接收電話號碼
5)讓用戶再次確認添加聯系人 1 確認 0 取消
6)保存聯系人信息到 聯系人數組中
7)讓聯系人的個數+1
8) 把最新的數組,重新保存到文件中
*/
void doAdd(){
printf("您正在執行的是添加聯系人的操作:\n");
//1. 提示用戶輸入聯系人信息
printf("請輸入聯系人姓名: [*聯系人姓名中間不能又空格]\n");
//2. 接受聯系人信息
char name[NAME_LEN];
char telNum[TELNUM_LEN];
scanf("%s",name);
//3.提示輸入電話號碼信息
printf("請輸入聯系人電話號碼: [*聯系人號碼中間不能有空格]\n");
//4)接收電話號碼
scanf("%s",telNum);
//5.讓用戶再確認
int queren = 0;
printf("修改后聯系人信息后,數據無法恢復,請確認修改:0.取消 1.確認\n");
scanf("%d",&queren);
if(queren){
strcpy(contacts[totalContactCount].name, name);
strcpy(contacts[totalContactCount].telNum, telNum);
// strcpy(contacts[totalContactCount].name,name);
//strcpy(contacts[totalContactCount].telNum,telNum);
totalContactCount++;
writeToFile();
}
printf("添加聯系人成功!\n");
}
/**
* 刪除聯系人
1)提示用戶輸入一個要刪除的聯系人的編號
2)判斷編號是否合法
3)再判斷 要刪除的元素 是否是數組的最后一個元素
如果是最后一個元素,總人數-1
如果不是最后一個元素,也就是中間的元素
移動元素
i = 編號 i< 總 i++
a[編號-1] = a[編號]
總人數-1
4)同步寫入到文件中
*/
void doDelete(){
printf("您正在執行的是刪除聯系人的操作:\n");
doList();
// 1 . 提示用戶輸入uige要刪除的聯系人的編號
int nn;
printf("請輸入一個要刪除的聯系人的編號:\n");
scanf("%d",&nn);
if(nn<1||nn>totalContactCount){
return;
}
int queren = 0;
printf("聯系人刪除后,無法恢復,請確認是否要刪除:0 取消 1 確認");
scanf("%d",&queren);
if(queren){
if(nn==totalContactCount){
totalContactCount--;
}else{
for(int i = nn; i <totalContactCount;i++){
contacts[i-1]=contacts[i];
}
totalContactCount--;
}
writeToFile();
}
}
/**
* 修改聯系人
1) 提示用戶輸入一個聯系人的編號
2) 判斷編號是否合法
3)讓用戶輸入新的聯系人姓名和電話
4) 接收用戶的輸入
5)讓用戶再次確認刪除
6)把原來的姓名和電話進行更新
7)同步保存到文件中
*/
void doUpdate(){
printf("您正在執行的是修改聯系人操作:\n");
doList();
int nn;
printf("請輸入一個要修改聯系人的編號:\n");
scanf("%d",&nn);
if(nn<1||nn>totalContactCount){
return;
}
char name[NAME_LEN];
char telNum[TELNUM_LEN];
printf("請輸入聯系人的姓名: 【*聯系人姓名中間不能有空格】");
scanf("%s",name);
printf("請輸入聯系人的電話: 【*聯系人電話中間不能有空格】");
scanf("%s",telNum);
int queren = 0;
printf("修改后的聯系人信息后,數據無法恢復,請確認修改: 0 取消 1 確認");
scanf("%d",&queren);
if(queren){
strcpy(contacts[nn-1].name,name);
strcpy(contacts[nn-1].telNum,telNum);
writeToFile();
}
}
/**
* 查詢所有的聯系人
思路:
1)先判斷 totalContactCount == 0
如果等于0 表示沒有聯系人,提示:通訊錄空無一人
不等于0 打印所有的聯系人
2)循環
3)遍歷輸出所有的聯系人信息
*/
void doList(){
printf("您正在執行的是查詢所有的聯系人的操作:\n");
if(totalContactCount==0){
printf("您的通信錄還很寂寞!\n");
}else{
printf("編號\t\t姓名\t\t電話\t\t\n");
for(int i = 0 ; i<totalContactCount;i++){
printf("%d\t\t%s\t\t%s\t\t\n",i+1,contacts[i].name,contacts[i].telNum);
}
}
}
/**
* 搜索聯系人
1) 提示用戶輸入一個聯系人的姓名
2)接收這個姓名
3)循環,遍歷數組
//進行字符串的比較
//strcmp(contacts[i].name,name) == 0
//如果查找到了,輸出這個聯系人的電話號碼
//如果沒有查找到,提示:沒有查找到
*/
void doSearchByName(){
printf("您正在執行的是搜索聯系人的操作:\n");
char name[NAME_LEN];
printf("請輸入聯系人的姓名: 【*聯系人的姓名中間不能有空格\n】");
scanf("%s",name);
int i ;
for( i = 0 ; i < totalContactCount;i++){
if(strcmp(contacts[i].name,name)==0){
printf("您要查的聯系人:%s的電話是:%s\n",name,contacts[i].telNum);
break;
}
}
if(i==totalContactCount){
printf("對不起沒有查到%s這個人!",name);
}
}
/**
* 初始化函數
思路:
1)定義文件指針,并且(嘗試)打開文件
2)如果能夠打開這個文件(說明文件已經存在了)
i.把文件中存放聯系人數量讀取出來
ii.根據聯系人的數量,把聯系人信息全部讀取出來,放到聯系人數組中
如果文件打開失敗了
i.創建文件
ii.寫入聯系人數量 0
3)關閉文件指針
*/
void init(){
printf("系統正在初始化.......\n");
FILE *fp = fopen(filePath,"r");
if(fp!=NULL){
fread(&totalContactCount,sizeof(totalContactCount),1,fp);
for(int i = 0 ; i < totalContactCount;i++){
fread(&contacts[i],sizeof(Person),1,fp);
}
}else{
fp = fopen(filePath,"w");
fwrite(&totalContactCount,sizeof(totalContactCount),1,fp);
printf("通訊錄文件創建成功!\n");
}
fclose(fp);
fp=NULL;
printf("系統初始化完成!\n");
}
/**
* 把數組的內容重新寫入到文件中
1)打開文件,w
2)判斷是否打開成功
3)先把聯系人的數量寫入到文件中
4)把每個聯系人的數據,都寫入到文件中
5)關閉文件
*/
void writeToFile(){
FILE *fp = fopen(filePath,"w");
if(fp!=NULL){
fwrite(&totalContactCount,sizeof(totalContactCount),1,fp);
for(int i = 0 ; i < totalContactCount;i++){
fwrite(&contacts[i],sizeof(Person),1,fp);
}
printf("數據更新完畢!\n");
}
fclose(fp);
}