读写文件的案例

本文介绍了一个简单的文件配置管理系统,通过使用C语言实现对文件进行读写操作的功能。系统支持用户输入键值对并将其写入文件,同时也能够从文件中读取指定键对应的值。

常用API函数:
//C 库函数 int fseek(FILE *stream, long int offset, int whence)
//设置流 stream 的文件位置为给定的偏移 offset,参数 offset 意味着从给定的 whence 位置查找的字节数。

///C 库函数 long int ftell(FILE* stream) 返回给定流 stream 的当前文件位置。该函数返回位置标识符的当前值

//C 库函数 char *fgets(char *str, int n, FILE *stream)
//从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。
//当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。

//C 库函数 char* strstr(const char* haystack, const char* needle)
//在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 ‘\0’。
//该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。

//C 库函数 char* strcat(char* dest, const char* src) 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
//该函数返回一个指向最终的目标字符串 dest 的指针。

//C 库函数 int fprintf(FILE* stream, const char* format, …) 发送格式化输出到流 stream 中。

test.cpp

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <Windows.h>
#include "fun.h"
#define FILE_NAME  "C:/Users/ky/Desktop/3.txt"


void mymenu()
{
	printf("=============================\n");
	printf("1 测试写配置文件\n");
	printf("2 测试读配置文件\n");
	printf("0 退出\n");
	printf("=============================\n");
}

int test_write()
{
	int		ret = 0;
	//读配置项 
	char	name[1024] = { 0 };
	char	valude[1024] = { 0 };
	int		wlen = 0;
	  
	printf("\n请键入key:");
	scanf("%s", name);

	printf("\n请键入valude:");
	scanf("%s", valude);

	ret = write_file(FILE_NAME, name, valude, strlen(valude));

	if (ret != 0)
	{
		printf("func WriteCfgItem err:%d \n", ret);
		return ret;
	}
	return 0;
}
int test_read()
{
	int		ret = 0;
	//读配置项 
	char	name[1024] = { 0 };
	char	buf[1024] = { 0 };
	int		rlen = 0;

	printf("\n请键入key:");
	scanf("%s", name);

	
	ret = read_file(FILE_NAME, name, buf, &rlen);

	if (ret != 0)
	{
		printf("func WriteCfgItem err:%d \n", ret);
		return ret;
	}
	printf("buf: %s\n", buf);
	return 0;
}
void main()
{
	
	int choice;

	for (;;)
	{
		mymenu();
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:
			test_write();
			break;
		case 2:
			test_read();
			break;
		case 0:
			exit (0);
			break;
		default:
			exit(0);
			break;
		}
	}

	return;

}

fun.h

#ifndef _FUN_H_
#define _FUN_H_



#ifdef  __cplusplus
extern "C" {
#endif

	int write_file(const char* filename, const char* key, const char* valude, int len);

	int read_file(const char* filename, const char* key,  char* buf, int *len);


#ifdef  __cplusplus
}
#endif


#endif

fun.cpp

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <Windows.h>
#include "fun.h"
#define MaxLine 2048 


//循环读每一行,检查key配置项是否存在 若存在修改对应value值
//若不存在,在文件末尾 添加 "key = value"
int write_file(const char* filename, const char* key, const char* valude,int len)
{
	int		rv = 0, iTag = 0, length = 0;
	FILE* fp = NULL;
	char	lineBuf[MaxLine];
	char* pTmp = NULL, * pBegin = NULL, * pEnd = NULL;
	char	filebuf[1024 * 8] = { 0 };

	if (filename == NULL || key == NULL || valude == NULL)
	{
		rv = -1;
		printf("SetCfgItem() err. param err \n");
		goto End;
	}

	fp = fopen(filename, "r+");
	if (fp == NULL)
	{
		rv = -2;
		printf("fopen() err. \n");
		//goto End;
	}

	if (fp == NULL)
	{
		fp = fopen(filename, "w+t");
		if (fp == NULL)
		{
			rv = -3;
			printf("fopen() err. \n");
			goto End;
		}
	}

	fseek(fp, 0L, SEEK_END); //把文件指针从0位置开始,移动到文件末尾
	//获取文件长度;
	length = ftell(fp);

	fseek(fp, 0L, SEEK_SET);

	if (length > 1024 * 8)
	{
		rv = -3;
		printf("文件超过1024*8, nunsupport");
		goto End;
	}

	while (!feof(fp))//目的是打造一个新的filebuf
	{
		//读每一行
		memset(lineBuf, 0, sizeof(lineBuf));
		pTmp = fgets(lineBuf, MaxLine, fp);//每次读一行到linebuf中
		if (pTmp == NULL)
		{
			break;
		}

		//key关键字是否在本行
		pTmp = strstr(lineBuf, key);
		if (pTmp == NULL) //key关键字不在本行, copy到filebuf中
		{
			strcat(filebuf, lineBuf);
			continue;    //continue终止本次循环,接着还执行后面的循环
		}
		else  //key关键在在本行中,替换旧的行,再copy到filebuf中 
		{
			sprintf(lineBuf, "%s = %s\n", key, valude);
			strcat(filebuf, lineBuf);
			//若存在key
			iTag = 1;
		}
	}

	//若key关键字,不存在 追加
	if (iTag == 0)
	{
		fprintf(fp, "%s = %s\n", key, valude);
	}
	else //若key关键字,存在,则重新创建文件
	{
		if (fp != NULL)
		{
			fclose(fp);
			fp = NULL; //避免野指针
		}

		fp = fopen(filename, "w+t");
		if (fp == NULL)
		{
			rv = -4;
			printf("fopen() err. \n");
			goto End;
		}
		fputs(filebuf, fp);
		//fwrite(filebuf, sizeof(char), strlen(filebuf), fp);
	}

End:
	if (fp != NULL)
	{
		fclose(fp);
	}
	return rv;
	return 0;
}

int read_file(const char* filename, const char* key,  char* buf,int* len)
{

	int		ret = 0;
	FILE* fp = NULL;
	char* pTmp = NULL, * pEnd = NULL, * pBegin = NULL;

	char lineBuf[MaxLine];
	 
	fp = fopen(filename, "r");
	if (fp == NULL)
	{
		ret = -1;
		return ret;
	}

	while (!feof(fp))
	{
		memset(lineBuf, 0, sizeof(lineBuf));
		//fgets(_Out_z_cap_(_MaxCount) char * _Buf, _In_ int _MaxCount, _Inout_ FILE * _File);
		fgets(lineBuf, MaxLine, fp);
		//printf("lineBuf:%s ",lineBuf );

		pTmp = strchr(lineBuf, '='); //
		if (pTmp == NULL) //没有=号
		{
			continue;
		}

		pTmp = strstr(lineBuf, key);
		if (pTmp == NULL) //判断key是不是在 //所在行 是不是有key
		{
			continue;
		}
		pTmp = pTmp + strlen(key); //mykey1 = myvalude11111111 ==> "= myvalude1111111"

		pTmp = strchr(pTmp, '=');
		if (pTmp == NULL) //判断key是不是在 //所在行 是不是有key
		{
			continue;
		}
		pTmp = pTmp + 1;
		//
		//printf("pTmp:%s ", pTmp);

		//获取value 起点
		while (1)
		{
			if (*pTmp == ' ')
			{
				pTmp++;
			}
			else
			{
				pBegin = pTmp;
				if (*pBegin == '\n')
				{
					//没有配置value
					//printf("配置项:%s 没有配置value \n", pKey);
					goto End;
				}
				break;
			}
		}

		//获取valude结束点
		while (1)
		{
			if ((*pTmp == ' ' || *pTmp == '\n'))
			{
				break;
			}
			else
			{
				pTmp++;
			}
		}
		pEnd = pTmp;

		//赋值
		*len = pEnd - pBegin;
		memcpy(buf, pBegin, pEnd - pBegin);
	}

End:
	if (fp == NULL)
	{
		fclose(fp);
	}
	return 0;
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值