这几天一直在整反汇编,经常看见函数GetPrivteProfileString,正好闲来无事,写点程序,目的主要在于熟悉Win32 API中文件操作和C语言对字符串的处理过程。
MFC中此函数GetPrivteProfileString可以用来读取配置文件.ini的函数,它在VS2008的msdn中的定义是这样的:
GetPrivateProfileString Function
Retrieves a string from the specified section in an initialization file.
翻译过来就是返回初始化文件中特定区域的字符串。参数如下:
DWORD WINAPI GetPrivateProfileString(
__in LPCTSTR lpAppName,
__in LPCTSTR lpKeyName,
__in LPCTSTR lpDefault,
__out LPTSTR lpReturnedString,
__in DWORD nSize,
__in LPCTSTR lpFileName
);
第一个LPCTSTR类型的lpAppName是定值区间,第二个是要读的字符串的名,第三个默认值为NULL,第四个为返回值,返回读到的字符串,第五个设置第四个参数(字符串)的大小,第六个为初始化文件路径。
这里假设初始化文件如下:
[function]
func1 = init
func2 = paint
func3 = read
func4 = write
func5 = exit
[parameter]
para1 = void
para2 = GDI
para3 = file
para4 = string
para5 = handle
我们要读取func2的值,那么读取方法就是
CString strVal;
DWORD size = 1000;
GetPraviteProfileString(_T("function"),_T("func2"),_T("Not Found"),strVal,GetBuffer(size),size,path);
_T("Not Found")为默认字符,即没找到时返回的值,path为文件路径。
然而当我们在移植程序到嵌入式系统时,这样的MFC函数是要不得的,我所使用的方法就是重写这个函数,用C语言写说到底就是字符串匹配的过程了,涉及到文件的就变成了FILE或fstream了,这里选用FILE,看代码吧
#define MAX_STRLEN 65 //规定最长字符串长度,分配内存、拷贝用
#define MAX_NUM 100 //规定最多可存储的单元数
typedef struct
{
char func[MAX_STRLEN];
char *data;
}FUNC;
typedef struct
{
char para[MAX_STRLEN];
char *data;
}PARA;
//分别用于存储function和parameter
FUNC *func;
PARA *para;
bool Mine_Init(char* cfg_filename)
{
func = (FUNC*)malloc(sizeof(FUNC)*MAX_NUM);
para = (PARA*)malloc(sizeof(PARA)*MAX_NUM);
FILE *in_fp;
char in_buf[MAX_STRLEN] = {0}; /* 从文件中读出的每一行的缓冲区 */
FUNC *ptrf = NULL;
PARA *ptrp = NULL;
char *str = NULL;
char substr[] = "\n";
bool is_func = false;
bool is_para = false;
int index_func = 0;
int index_para = 0;
in_fp = fopen (cfg_filename, "r");
if (in_fp == NULL)
{
printf("\nError, %s not found!",cfg_filename);
return false;
}
while (fgets(in_buf,sizeof(in_buf),in_fp) != NULL)
{
str = strpbrk(in_buf,substr);
*str = '\0';
if (!strcmp(in_buf,"[function]"))
{
//存function
ptrf = (FUNC*)func;
is_func = true;
}
else if(!strcmp(in_buf,"[parameter]"))
{
//存parameter
ptrf = NULL;//读完function的值,要把指针清掉,否则又会跳进Write_FUNC
ptrp = (PARA*)para;
is_para = true;
}
else if (ptrf != NULL)
{
if ( Write_FUNC(ptrf, in_buf, in_fp, index_func, is_func) == -1)//写
入function值
{
return false;
}
}
else if (ptrp != NULL)
{
if ( Write_PARA(ptrp, in_buf, in_fp, index_para, is_para) == -1)//写
入parameter值
{
return false;
}
}
else
{
fclose(in_fp);
return false;
}
}
fclose(in_fp);
return true;
}
下面是两个写入数据结构的函数,我的程序不能随机的读某个节点,只能一次性将节点全部读入数据结构
里存储,有更好的方法还望指教!!
int Write_FUNC(FUNC* ptr, char* in_buf, FILE *in_fp, int& index_func, bool is_func)
{
assert(ptr && in_fp);
memcpy(ptr, in_buf, MAX_STRLEN);
if (is_func)
{
ZeroMemory(in_buf, MAX_STRLEN);
fgets(in_buf, MAX_STRLEN, in_fp);
(func + index_func)->data = (char*)malloc(MAX_STRLEN);//这里要初始化,否则会
出错
memcpy((func + index_func)->data,in_buf,MAX_STRLEN);
index_func++;
}
return 0;
}
int Write_PARA(PARA* ptr, char* in_buf, FILE *in_fp, int& index_para, bool is_para)
{
assert(ptr && in_fp);
memcpy(ptr, in_buf, MAX_STRLEN);
if (is_para)
{
ZeroMemory(in_buf, MAX_STRLEN);
fgets(in_buf, MAX_STRLEN, in_fp);
(para + index_para)->data = (char*)malloc(MAX_STRLEN);
memcpy((para + index_para)->data,in_buf,MAX_STRLEN);
index_para++;
}
return 0;
}
从函数中可以看到,in_buf是一行一行的读取到数据的,所以对应的配置文件格式也要有所变化
[function]
func1
init
func2
paint
func3
read
func4
write
func5
exit
[parameter]
para1
void
para2
GDI
para3
file
para4
string
para5
handle
声明:是从本人CSDN上的同名文章转载过来的,纯属原创,转载请注明
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!