这几天一直在整反汇编,经常看见函数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上的同名文章转载过来的,纯属原创,转载请注明