一,示例需求介绍
介绍一个关于C语言的文件操作的例子.
在磁盘某个位置存放某个文件, 该文件用来保存输入的键值对(key-value).
例子具有以下功能
1,持久化的按行存放键值对(key-value),不支持重复的key
2,根据key查找对应的value , 查到对应的value显示, 不存在提示
3,退出功能
二,思路
<一>
根据需求我们需要封装两个功能”库函数” 提供存放
//存储指定的键值对到文件 不支持重复的key
int putConfigItem(char* filename/*in*/, char*key,/*in*/ char* value /*in*/)
另外一个函数提供读取
//根据key获取value
int getConfigItem(char* filename/*in*/, char *key,/*in*/char* value/*in*/)
为了查找是否存在对应的key和存放时候判断是否存在重复的key定义一个不对外暴漏的函数
//判断某个是字符串是否以特定的前缀开头
BOOL startWithSuffix(char* src, char* suffix)
<二>然后通过一个死循环提示对应的操作,通过scanf输入对应的key value进行存储, 对应的key查找value
//显示界面和控制逻辑
void configFile(){
int retCode = 0;
printf("\n请选择选项:");
while(1){
char choice = 0;
scanf("%c",&choice);
switch(choice){
case PUT_VALUE:
retCode = putItem();
if(retCode ==0 ){
printf("存储成功\n");
}
break;
case GET_VALUE:
retCode = getItem();
break;
case EXIT:
return;
default:
printf("\n请选择选项:");
}
}
}
三,对应的代码如下
// ConfigFile.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<stdlib.h>
#include<string.h>
#define PUT_VALUE '1'
#define GET_VALUE '2'
#define EXIT '0'
#define TRUE 1
#define FALSE 0
#define FILE_NAME "c:/config.ini"
typedef int BOOL;
//判断某个是字符串是否以特定的前缀开头
BOOL startWithSuffix(char* src, char* suffix){
if(src == NULL || suffix == NULL){
printf("参数错误\n");
return FALSE;
}
char* tmpSrc = src;
char* tmpSuffix = suffix;
int counter = 0;
while(*tmpSrc != '\0' && *tmpSuffix != '\0'){
if((*tmpSrc == *tmpSuffix)){
counter ++;
tmpSrc++;
tmpSuffix++;
}else{
break;
}
}
if(counter != strlen(suffix)){
return FALSE;
}
return TRUE;
}
//存储指定的键值对到文件 不支持重复的key
int putConfigItem(char* filename/*in*/, char*key,/*in*/ char* value /*in*/){
int retCode = 0;
//1,打开文件
FILE *fp = NULL;
fp = fopen(filename,"a+");
if(fp == NULL){
retCode = -1;
printf("文件打开失败. ErroCode:%d\n",retCode);
return retCode;
}
//2,判断是否有重复的文件
char buf[64];
char tempKey[64] = {0};
strcpy(tempKey,key);
strcat(tempKey,"=");
while(!feof(fp)){
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf)/sizeof(char),fp);
BOOL isSuffix = startWithSuffix(buf,tempKey);
if(isSuffix == TRUE){
retCode = -4;
printf("键:%s已经存在\n",key);
return retCode;
}
}
//3,存放键值对
char tempBuf[256];
memset(tempBuf,0,sizeof(tempBuf));
strcat(tempBuf,key);
strcat(tempBuf,"=");
strcat(tempBuf,value);
printf("%s",tempBuf);
fputs(tempBuf,fp);
fputs("\n",fp);
if(fp != NULL){
fclose(fp);
fp = NULL;
}
return retCode;
}
//根据key获取value
int getConfigItem(char* filename/*in*/, char *key,/*in*/char* value/*in*/){
int retCode = 0;
//1,打开文件
FILE *fp = NULL;
fp = fopen(filename,"a+");
if(fp == NULL){
retCode = -1;
printf("文件打开失败. ErroCode:%d\n",retCode);
return retCode;
}
//2,根据key查找value
char buf[64];
char tempKey[64] = {0};
strcpy(tempKey,key);
strcat(tempKey,"=");
while(!feof(fp)){
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf)/sizeof(char),fp);
BOOL isSuffix = startWithSuffix(buf,tempKey);
if(isSuffix == TRUE){
char temp[64]={0};
for(int i = strlen(key)+1; i<= strlen(buf); i++){
char c[2] = {0};
*c = *(buf+i);
strcat(temp,c);
}
strcat(buf,"\0");
printf("得到的value是:%s\n",temp);
return retCode;
}
}
if(fp != NULL){
fclose(fp);
fp = NULL;
}
printf("key: %s对应的value未找到\n",key);
retCode = -3;
return retCode;
}
/******************************************************************/
/*以上是抽取库函数*/
/*以下是功能实现*/
/******************************************************************/
void showTips(){
printf("=============================================\n");
printf("1 存储或者修改key-value\n");
printf("2 获取key-value\n");
printf("0 退出系统\n");
printf("=============================================\n");
}
//存储键值对的调用
int putItem(){
int ret = 0;
char key[64];
char value[64];
printf("\n 请输入key:");
scanf("%s",key);
printf("\n 请输入value:");
scanf("%s",value);
ret = putConfigItem(FILE_NAME,key,value);
return ret;
}
//获取键值对的调用
int getItem(){
int ret = 0;
char key[64]={0};
char value[64]={0};
printf("\n 请输入key:");
scanf("%s",key);
ret = getConfigItem(FILE_NAME,key,value);
return ret;
}
//显示界面和控制逻辑
void configFile(){
int retCode = 0;
printf("\n请选择选项:");
while(1){
char choice = 0;
scanf("%c",&choice);
switch(choice){
case PUT_VALUE:
retCode = putItem();
if(retCode ==0 ){
printf("存储成功\n");
}
break;
case GET_VALUE:
retCode = getItem();
break;
case EXIT:
return;
default:
printf("\n请选择选项:");
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
showTips();
configFile();
return 0;
}