奇葩版 - fscanf

最近在幫媽媽寫一個(gè)類似工具箱的小程序時(shí)脖含,要用到讀取配置文件的功能窖杀。一開始用的是:fgets,一行一行地讀取再用strtok對(duì)內(nèi)容進(jìn)行分割调衰。

后來無意中看到一篇文章(文章標(biāo)題好像是《fscanf讀取一行...》在此感謝這位同學(xué))膊爪,發(fā)現(xiàn)fscanf可以直接以格式化讀取文件。

我們先看看 fscanf 函數(shù):
int fscanf(FILE*stream, constchar*format, [argument...]); 

其中最重要也最難理解的是第二個(gè)參數(shù):format嚎莉。這個(gè)參數(shù)的一般用法和scanf一樣米酬,網(wǎng)上到處都是,這里不再贅述趋箩。
我們要研究的是我們的配置文件如何按格式讀取赃额,來看一個(gè)配置文件的例子:

vc6 = C:\Program Files\VC6EN\COMMON\MSDEV98\BIN\MSDEV.EXE
python = C:\python36\python.exe

這是配置文件的一般形式(注意“=”左右側(cè)有空格),根據(jù)fscanf讀取的特性:在遇到空格或換行的時(shí)候停止讀取叫确。
那我們就可以這樣讀取全部信息:

int main(int argc, char* argv[])
{
    FILE *fpconf;
    fpconf = fopen("D:\\configure", "r"); //上面的配置信息寫在這個(gè)文件里
    if(!fpconf)
    {
        printf("讀取配置文件失斕肌!");
        return 1;
    }

    struct json
    {
        char key[256];
        char value[256];
    };

    struct json myconf;

    int index = 1;
    while(!feof(fpconf))
    {
        memset(&myconf, 0, sizeof(myconf));

        fscanf(fpconf, "%s = %s", myconf.key, myconf.value);  //這里注意 “=” 左右要有空格
        printf("第%d個(gè)應(yīng)用程序:%s, 路徑:%s\n", index, myconf.key, myconf.value);

        index++;
    }

    if(fpconf)
        fclose(fpconf);

    return 0;
}

運(yùn)行結(jié)果:

result1.jpg

可以看到竹勉,這明顯不是我們想要的結(jié)果飞盆。這是為什么呢,還是那個(gè)原因:在遇到空格或換行的時(shí)候停止讀取次乓。
因?yàn)榈谝粋€(gè)應(yīng)用程序的路徑中:C:\Program (這里有空格)Files\VC6EN\COMMON\MSDEV98\BIN\MSDEV.EXE吓歇,fscanf函數(shù)在這里停止了,把后面的內(nèi)容作為下一行來讀取票腰,所以出現(xiàn)了這樣的結(jié)果城看。
那么我們應(yīng)該怎么辦呢?這里要用到一個(gè)類似正則式的寫法:

...
fscanf(fpconf, "%s = %[^\n]", myconf.key, myconf.value);  //這里注意 “=” 左右要有空格
...

結(jié)果:

result2.jpg

可以看到杏慰,這里就是我們想要的運(yùn)行結(jié)果了测柠。
%[^\n]這是個(gè)什么東西呢?其實(shí)他類似于正則中的匹配逃默,意思是:不遇到“\n”就一直讀取鹃愤,那"\n"我們都知道簇搅,就是“換行”完域,而空格不是換行,所以就會(huì)把空格也讀取進(jìn)來瘩将,而不是遇到空格停止讀取吟税。


根據(jù)上面的功能引申一下:我們寫好程序凹耙,而其它人不知道編寫配置文件的規(guī)則,不知道要在 = 號(hào)兩邊加空格肠仪,而寫成這樣了:

vc6=C:\Program Files\VC6EN\COMMON\MSDEV98\BIN\MSDEV.EXE
python=C:\python36\python.exe

那會(huì)發(fā)生什么呢肖抱?我們來看看運(yùn)行結(jié)果:

result3.jpg

這明顯不是我們想要的。那我們又應(yīng)該怎么辦呢异旧?
首先我們分析一下配置文件的結(jié)構(gòu):
=號(hào)左側(cè)是一個(gè)字符串
=號(hào)右側(cè)也是一個(gè)字符串
所以它一定是用=號(hào)來分隔意述,根據(jù):不遇到XX就一直讀取這一原則,我們應(yīng)該把讀取格式寫成:

fscanf(fpconf, "%[^=] = %[^\n]\n", myconf.key, myconf.value);  //這里注意 “=” 左右要有空格

結(jié)果:


result4.jpg

這就是我們想要的了吮蛹。

這句話分成兩個(gè)部分來理解:

  1. %[^=] 理解為不遇到 = 號(hào)就一直讀然绯纭;
  2. %[^\n] 理解為不遇到換行就一直讀瘸闭搿(空格也讀仁趸纭)。

那為什么 %[^=] 之后還有一個(gè) = 號(hào)呢每篷?那是因?yàn)榘昶荩灰獩]有寫在“格式”中的字符或字符串,fscanf都會(huì)理解為是程序員想要的內(nèi)容焦读,并將其讀取到我們的變量中子库,所以如果我們不想要 = 這個(gè)字符,就要把它寫上吨灭,避免被讀取進(jìn)我們要的內(nèi)容中刚照。

到這里,這篇文章就寫完了喧兄,如果后續(xù)還有好玩的用法无畔,再更新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吠冤,一起剝皮案震驚了整個(gè)濱河市浑彰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拯辙,老刑警劉巖郭变,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異涯保,居然都是意外死亡诉濒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門夕春,熙熙樓的掌柜王于貴愁眉苦臉地迎上來未荒,“玉大人,你說我怎么就攤上這事及志∑牛” “怎么了寨腔?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長率寡。 經(jīng)常有香客問我迫卢,道長,這世上最難降的妖魔是什么冶共? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任乾蛤,我火速辦了婚禮,結(jié)果婚禮上捅僵,老公的妹妹穿的比我還像新娘幻捏。我一直安慰自己,他們只是感情好命咐,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布篡九。 她就那樣靜靜地躺著,像睡著了一般醋奠。 火紅的嫁衣襯著肌膚如雪榛臼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天窜司,我揣著相機(jī)與錄音沛善,去河邊找鬼。 笑死塞祈,一個(gè)胖子當(dāng)著我的面吹牛金刁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播议薪,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼尤蛮,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了斯议?” 一聲冷哼從身側(cè)響起产捞,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哼御,沒想到半個(gè)月后坯临,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恋昼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年看靠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片液肌。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挟炬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辟宗,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布吝秕,位于F島的核電站泊脐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏烁峭。R本人自食惡果不足惜容客,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望约郁。 院中可真熱鬧缩挑,春花似錦、人聲如沸鬓梅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绽快。三九已至芥丧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坊罢,已是汗流浹背续担。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留活孩,地道東北人物遇。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像憾儒,于是被迫代替她去往敵國和親询兴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容