基于文本和结构体的数据操作:
包含文件读写。
头文件:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*文件路径存储长度*/
#define MAX_PATH_LEN 128
/*文件数据字节数*/
#define MAX_LEN 1024
/*配置文件路径,存储数据文件地址*/
#define PATHINI "./Path.txt"
/*文件数据结构*/
struct info
{
char userID[12];
char pwd[16];
};
/*数据结构*/
struct infos
{
struct info* vPInfo;//数据
int length; //数据(个数)长度
};
typedef struct infos INFOS;
#pragma region 函数声明
/*
函数: 根据标识,读取文件内容
参数: char* vPtr:文件路径
int flag :标识(1,读取一行,2,读取整个文本)
返回值: 成功返回内容字符串指针
失败返回 NULL
*/
char* readPathInfo(char* vPtr, int flag,char *pVal);
/*
功能: 获取数据个数
参数:
char* vPtr :数据首地址指针
返回: 类型(int) ,数据个数
*/
int getnum(char* vPtr);
/*
初始化数据结构,开辟存储空间
*/
void init(char* str, INFOS* vPinto);
/*
功能: 初始化数据结构,填充数据
参数:
char* vPtr :数据首地址指针
返回:
无
*/
void initData(char* vPtr, INFOS* vPinto);
/*
功能: 显示所有数据
参数:
无
返回:
无
*/
void showInfo(INFOS* vPinto);
/*
功能: 根据账号查找数据
参数:
char* vPID :账号
INFOS* vPinto :数据结构指针
返回:
无
*/
void showFindInfo(char* vPID, INFOS* vPinto);
/*
功能: 根据账号查找数据,并修改
参数:
char* vPID :账号
INFOS* vPinto :数据结构指针
char *pNewStr : 新密码
返回:
无
*/
void modifyInfo(char* vPID, INFOS* vPinfo,char *pNewStr);
/*
功能: 添加数据
参数:
char* id :账号
INFOS* vPinto :数据结构指针
char* pwd : 密码
返回:
无
*/
void addInfo(char* id, char* pwd, INFOS* vPinfo);
/*
功能: 删除数据
参数:
char* id :账号
INFOS* vPinto :数据结构指针
返回:
无
*/
void deleteInfo(char* id,INFOS* vPinfo);
/*清除字符串*/
int clearMem(char* vPtr);
#pragma endregion
源文件:
#define _CRT_SECURE_NO_WARNINGS
#include"info.h"
/*显示所有数据*/
void showInfo(INFOS* vPinfo)
{
for (int i = 0; i < vPinfo->length; i++)
{
printf("账号:%s ; 密码:%s \n", vPinfo->vPInfo[i].userID, vPinfo->vPInfo[i].pwd);
}
}
/*
初始化内存空间数据
*/
void initData(char* vPtr, INFOS* vPinfo)
{
int len = strlen(vPtr);
char* head = vPtr;
int i = 0;//拷贝位置下标
int tag = 0;//字符串指针下标
int index = 0;//元素下标
for (char* p = vPtr; p < vPtr + len; p++)
{
tag++;
if (*p == '\n')//使用文本中 '\n' 作为分割符,文本结尾必须包含'\n'结束符。
{
int n = p - head;
char* pNew = malloc(sizeof(char) * n);
if (pNew != NULL)
{
strncpy(pNew, vPtr + i, n);
pNew[n] = '\0';
//printf("%s\n", pNew);
char* vFlag = strchr(pNew, '-');
*vFlag = '\0';
//sscanf(pNew, "%lld", &info_Data.vPInfo[index].userID);
sprintf(vPinfo->vPInfo[index].userID, "%s", pNew);//填充账号
sprintf(vPinfo->vPInfo[index].pwd, "%s", vFlag + 4);//填充密码
head = p + 1;//前进一个字节指针,去掉'\n'
i = tag;
index++;
}
}
}
}
/*
初始化内存空间
*/
void init(char *str, INFOS* vPinto)
{
int len = getnum(str);//获取数据个数
int n = sizeof(struct info);
vPinto->vPInfo = malloc(sizeof(struct info) * len);//分配内存
vPinto->length = len;//保存数个数
}
/*
获取数据个数
*/
int getnum(char* vPtr)
{
int n = 0;
for (char* pStr = strstr(vPtr, "----"); pStr != NULL; pStr = strstr(pStr + 4, "----"))
{
n++;
}
return n;
}
/*
函数: 根据标识,读取文件内容
参数: char* vPtr:文件路径
int flag :标识(1,读取一行,2,读取整个文本)
char* pVal: 存储结果
返回值: 成功返回内容字符串指针
失败返回 NULL
*/
char* readPathInfo(char* vPtr, int flag, char* pVal)
{
FILE* pf = fopen(vPtr, "a+");
int len;
if (pf != NULL)
{
if (flag == 1)
{
while (fgets(pVal, MAX_PATH_LEN, pf) != NULL)//读取一行
{
len = strlen(pVal);//获取字符个数
pVal[len] = '\0'; //去掉换行符
}
}
else
{
fread(pVal, MAX_LEN, 1, pf);
}
fclose(pf);
}
if (flag == 1)
{
if (strlen(pVal) > 0)
{
return pVal;
}
else
{
return NULL;
}
}
else
{
if (strlen(pVal) > 0)
{
return pVal;
}
else
{
return NULL;
}
}
}
/*
功能: 根据账号查找数据
参数:
char* vPID :账号
INFOS* vPinto :数据结构指针
返回:
-1 或 对应下标
*/
int findInfo(char* vPID, INFOS* vPinfo)
{
if (vPinfo == NULL || vPID == NULL)
{
return -1;
}
for (int i = 0; i < vPinfo->length; i++)
{
if (strcmp(vPinfo->vPInfo[i].userID, vPID)==0)
{
return i;
}
}
return -1;
}
/*
功能: 根据账号查找数据,并显示
参数:
char* vPID :账号
INFOS* vPinto :数据结构指针
返回:
0 或 1
*/
void showFindInfo(char* vPID, INFOS* vPinfo)
{
int n = findInfo(vPID, vPinfo);
if (n)
{
printf("找到信息如下:\n");
printf("账号:%s ; 密码:%s \n", vPinfo->vPInfo[n].userID, vPinfo->vPInfo[n].pwd);
}
else
{
printf("未找到指定元素!");
}
}
/*
功能: 根据账号查找数据,并修改
参数:
char* vPID :账号
INFOS* vPinto :数据结构指针
char *pNewStr : 新值
返回:
无
*/
void modifyInfo(char* vPID, INFOS* vPinfo, char* pNewStr)
{
int n = findInfo(vPID, vPinfo);
if (n)
{
printf("找到信息如下:\n");
printf("账号:%s ; 密码:%s \n", vPinfo->vPInfo[n].userID, vPinfo->vPInfo[n].pwd);
sprintf(vPinfo->vPInfo[n].pwd, "%s", pNewStr);//填充密码
printf("修改后信息如下:\n");
printf("账号:%s ; 密码:%s \n", vPinfo->vPInfo[n].userID, vPinfo->vPInfo[n].pwd);
}
else
{
printf("未找到指定元素!");
}
}
/*
功能: 添加数据
参数:
char* id :账号
INFOS* vPinto :数据结构指针
char* pwd : 密码
返回:
无
*/
void addInfo(char* id, char* pwd, INFOS* vPinfo)
{
if (id == NULL || pwd == NULL)
{
return;
}
int lenid = strlen(id);
if (lenid > 11)
{
printf("账号数据长度不能超过11位 \n");
return;
}
int lenPwd = strlen(pwd);
if (lenPwd > 15)
{
printf("密码数据长度不能超过15位 \n");
return;
}
int num = vPinfo->length;
struct info * p=(struct info*)(realloc(vPinfo->vPInfo,sizeof(struct info) * (num+1)));//存储空间加1
if (p != NULL)
{
vPinfo->vPInfo = p;
sprintf(vPinfo->vPInfo[vPinfo->length].pwd, "%s", pwd);//填充密码
sprintf(vPinfo->vPInfo[vPinfo->length].userID, "%s", id);//填充账号
vPinfo->length = num + 1;//数据个数加1
printf("数据添加成功!\n");
return;
}
else
{
free(p);
}
printf("数据添加失败!\n");
}
/*
功能: 删除数据
参数:
char* id :账号
INFOS* vPinto :数据结构指针
返回:
无
*/
void deleteInfo(char* id, INFOS* vPinfo)
{
int n = findInfo(id, vPinfo);
if (n > 0)
{
int n1 = clearMem(vPinfo->vPInfo[n].pwd);
int n2 = clearMem(vPinfo->vPInfo[n].userID);
if ((n1 + n2) == 2)
{
int num = vPinfo->length;
struct info* p = (struct info*)(realloc(vPinfo->vPInfo, sizeof(struct info) * (num - 1)));//存储空间减1
if (p != NULL)
{
vPinfo->vPInfo = p;
vPinfo->length = num - 1;
printf("删除成功!\n");
}
}
}
else
{
printf("未找到指定账号:【 %s 】 的数据!\n", *id);
}
}
int clearMem(char* vPtr)
{
if (vPtr == NULL)
{
return 0;
}
while (*vPtr!='\0')
{
*vPtr = '\0';
vPtr++;
}
return 1;
}
资源文件:Path.txt
调用:
#define _CRT_SECURE_NO_WARNINGS
#include"info.h"
/*存储文件路径*/
char path[MAX_PATH_LEN] = { 0 };
/*存储文件数据*/
char str[MAX_LEN] = { 0 };
/*全局公共数据结构*/
INFOS info_Data;
char id[15] = { 0 };
char value[20] = { 0 };
void promptMessage();
void saveData();
void main()
{
char *pPath= readPathInfo(PATHINI,1,path);
if (pPath != NULL)
{
char *pInfo= readPathInfo(pPath,0,str);
if (pInfo != NULL)
{
init(pInfo, &info_Data);
initData(str, &info_Data);
printf("数据读取,并初始化成功!");
promptMessage();
while (1)
{
char ch = getchar();
switch (ch)
{
case '1':
showInfo(&info_Data);
break;
case '2':
printf("请输入账号: \n");
int n5 = scanf("%s", id);
deleteInfo(id, &info_Data);
clearMem(id);
break;
case '3':
printf("请输入账号: \n");
int n3 = scanf("%s", id);
printf("请输入新值: \n");
int n4 = scanf("%s", value);
addInfo(id, value, &info_Data);
clearMem(id);
clearMem(value);
break;
case '4':
printf("请输入账号: \n");
int n1 = scanf("%s", id);
printf("请输入新值: \n");
int n2 = scanf("%s", value);
modifyInfo(id, &info_Data, value);
clearMem(id);
clearMem(value);
break;
case '5':
printf("请输入账号: \n");
int n=scanf("%s", id);
showFindInfo(id, &info_Data);
clearMem(id);
break;
case '6':
saveData();
break;
case '7':
system("cls");
break;
case '8':
promptMessage();
break;
default:
break;
}
}
showInfo(&info_Data);
}
else
{
printf("读取数据文件错误,程序终止!");
}
}
else
{
printf("读取配置文件路径错误,程序终止!");
}
system("pause");
}
/*
显示提示信息
*/
void promptMessage()
{
printf("\n---------- 操作提示 ----------\n\n");
printf("【%d】: %s\n【%d】: %s\n【%d】: %s\n【%d】: %s\n【%d】: %s\n【%d】: %s\n【%d】: %s\n【%d】: %s\n",
1,"显示数据",
2,"删除数据",
3,"插入数据",
4,"修改数据",
5,"查找数据",
6,"保存数据",
7,"清屏",
8,"显示帮助");
printf("\n---------- ***** ----------\n");
}
/*
保存数据
*/
void saveData()
{
char info[128] = { 0 };
if (info != NULL)
{
for (int i = 0; i < info_Data.length; i++)
{
strcat(info, info_Data.vPInfo[i].userID);
strcat(info, "----");
strcat(info, info_Data.vPInfo[i].pwd);
char cmd[128];
if (i == 0)
{
sprintf(cmd, "echo %s > %s", info, path);//重写 >
}
else
{
sprintf(cmd, "echo %s >> %s", info, path);//追加 >>
}
system(cmd);//执行指令
clearMem(info);
}
printf("保存成功!\n");
}
}
外部文件格式:
效果: