閱讀302 返回首頁    go 技術社區[雲棲]


C語言讀取配置文件的另類寫法

前些天寫了一篇《標準輸出的重定向》,這幾天又遇到了讀取配置文件的任務,想一改原來的" FILE* fp ……"之類的寫法,換用一種新的靈活性更高的方式,即把標準輸出重定向到一個管道的寫端,再從管道的讀端獲取內容。

    首先我們有這樣一個函數,用來獲取system調用的輸出:

static int getResultFromSystemCall(const char* pCmd, char* pResult, int size)
{
   int fd[2];
   if(pipe(fd))   {
      printf("pipe error!\n");
      return -1;
   }

   //hide stdout
   int bak_fd = dup(STDOUT_FILENO);
   int new_fd = dup2(fd[1], STDOUT_FILENO);

   //the output of `pCmd` writes into fd[1]
   system(pCmd);
   read(fd[0], pResult, size-1);
   pResult[strlen(pResult)-1] = 0;

   //resume stdout
   dup2(bak_fd, new_fd);

   return 0;
}

這樣,我們可以通過下麵的形式調用它:

   char cmd[100] = {0};
   getResultFromSystemCall("export aaa=1234 && echo ${aaa#=}", res, sizeof(res)/sizeof(res[0]));

我們可以獲得 1234 這個值了。

我們把該函數的第一個參數再弄的複雜一點,如

cat test.conf | grep -m 1 -E "^aaa" | cut -d= -f2 | sed 's/[[:space:]]*//g'

下麵解釋一下,各牛們請飄過:

#aaa is test key
aaa =     	   1234
aaa =  bbbb

test.conf 內容如上。

第一層管道的grep,-m 1 指定了我們隻獲取符合條件的第一行, -E 指定使用grep的擴展形式,也可以用 egrep 代替 grep -E , "^aaa"  指定了以aaa開頭行的條件,用來回避#開頭的注釋行。
第二層管道的cut,用來截取以 = 分割的第2個域。
第三層管道的sed,用來將 1234 前麵的各種tab和空格去掉。

 這樣的話,我們就有如下輸出結果了:

 tools.c 的代碼請見 https://www.oschina.net/code/snippet_616273_14056

我們可以把其中的main函數稍稍改裝一下,如

int readValueFromConf(const char* filePath, const char* key, char* res, int size)
{
   char cmd[100] = {0};
   sprintf(cmd, "cat %s | grep -m 1 -E \"^%s\" | cut -d= -f2 | sed 's/[[:space:]]*//g'", filePath, key); 
   return getResultFromSystemCall(cmd, res, size);
}

這樣,我們就完成了C語言讀取配置文件的另類寫法。

最後更新:2017-04-02 15:14:54

  上一篇:go 茵茵的第一課
  下一篇:go 16進製的簡單運算