302
技術社區[雲棲]
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