前言
在linux環(huán)境下,c語(yǔ)言的輸入輸出控制有其獨(dú)特的魅力和實(shí)際應(yīng)用場(chǎng)景。本文將從回車換行和緩沖區(qū)的基礎(chǔ)知識(shí)講起,帶領(lǐng)大家探索如何在linux環(huán)境中實(shí)現(xiàn)一個(gè)動(dòng)態(tài)倒計(jì)時(shí)功能,并進(jìn)一步完成一個(gè)具有交互感的進(jìn)度條。通過(guò)這些內(nèi)容,你不僅可以理解c語(yǔ)言在linux中的輸出行為,還能掌握如何通過(guò)代碼提升程序的可視化表現(xiàn)。無(wú)論是Linux開(kāi)發(fā)初學(xué)者,還是想深入了解c語(yǔ)言底層實(shí)現(xiàn)的同學(xué),這篇文章都將為你帶來(lái)新的啟發(fā)。
?一、預(yù)備知識(shí)?1.1 回車換行
真正意義上,回車換行其實(shí)是兩個(gè)動(dòng)作,在c語(yǔ)言中 卻同時(shí)完成了回車+換行的兩步動(dòng)作。
回車:將光標(biāo)移到當(dāng)前行的最左側(cè)換行:將光標(biāo)移到當(dāng)前行對(duì)應(yīng)位置的下一行
在C語(yǔ)言中可以使用轉(zhuǎn)義字符 來(lái)實(shí)現(xiàn)單獨(dú)的回車行為。
如圖展示以下以前的老式鍵盤(pán):

這種電腦鍵盤(pán)上的ENTER按鍵就是同時(shí)實(shí)現(xiàn)了回車和換行的功能,按下ENTER鍵,光標(biāo)會(huì)去到下一行的最左側(cè)的位置。
?1.2 緩沖區(qū)
先看一段代碼
代碼語(yǔ)言:JavaScript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制
這段代碼很簡(jiǎn)單,現(xiàn)在屏幕上打印出hello world,接著調(diào)用sleep函數(shù)讓程序休眠兩秒,

間隔兩秒后。

接下來(lái),我們對(duì)上面的代碼稍作修改,去掉 再來(lái)試試。
代碼語(yǔ)言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制
#include <unistd.h>int main() { printf("hello world"); sleep(2); return 0;}</unistd.h>
在去掉/n后對(duì)代碼編譯運(yùn)行,先是休眠了兩秒,

接著才在屏幕上打印出hello world,并且因?yàn)闆](méi)有 ,所以打印完后沒(méi)有換行,導(dǎo)致命令行提示符就緊跟在打印結(jié)果的后面。

情景分析
那么問(wèn)題來(lái)了,這段代碼是先執(zhí)行sleep,還是先執(zhí)行printf打印呢?
很多人會(huì)根據(jù)上面的現(xiàn)象猜測(cè),這段代碼先執(zhí)行了sleep休眠,再去執(zhí)行printf打印,這樣的猜測(cè)是錯(cuò)誤的!因?yàn)槿魏我粋€(gè)C語(yǔ)言程序,都是嚴(yán)格按照代碼的編寫(xiě)順序去執(zhí)行的。
那在休眠的兩秒期間,printf的打印結(jié)果存在哪里了呢?
hello world其實(shí)是保存在了緩沖區(qū)中,緩沖區(qū)是用于臨時(shí)存儲(chǔ)數(shù)據(jù)的內(nèi)存空間,默認(rèn)當(dāng)程序結(jié)束的時(shí)候才會(huì)將緩沖區(qū)中的內(nèi)容刷新出來(lái)。
如何強(qiáng)制刷新緩沖區(qū)
任何一個(gè)C語(yǔ)言程序運(yùn)行的時(shí)候都會(huì)默認(rèn)幫我們打開(kāi)以下三個(gè)流:
stdin – – – – 標(biāo)準(zhǔn)輸入流(鍵盤(pán))stdout – – – – 標(biāo)準(zhǔn)輸出流(顯示器)stderr – – – – 標(biāo)準(zhǔn)錯(cuò)誤(顯示器)

Linux下一切皆文件,這三個(gè)流都是FILE*的指針,所以任何一個(gè)C語(yǔ)言程序運(yùn)行的時(shí)候,操作系統(tǒng)會(huì)幫我們打開(kāi)以上三個(gè)文件。今天我們只需要關(guān)心stdout標(biāo)準(zhǔn)輸出流即可。我們可以通過(guò)fflush函數(shù)來(lái)刷新緩沖區(qū)。
代碼語(yǔ)言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制
#include <stdio.h>#include <unistd.h>int main(){ printf("hello world"); fflush(stdout); sleep(2); return 0;}</unistd.h></stdio.h>

等待兩秒后…

通過(guò)上面的分析我們可以得出,刷新緩沖區(qū)主要有以下幾種方法:
可以刷新緩沖區(qū)。程序結(jié)束也會(huì)刷新緩沖區(qū)。fflush(stdout)可以手動(dòng)刷新緩沖區(qū)。?二、倒計(jì)時(shí)
學(xué)習(xí)了上面的東西,我們可以先來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的倒計(jì)時(shí)練練手
?2.1 源代碼代碼語(yǔ)言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制
#include "processBar.h"#include <unistd.h>int main(){int cnt = 10;while(cnt >= 0){printf("%-2d ",cnt);fflush(stdout);sleep(1);cnt--;}printf(" "); return 0;}</unistd.h>
?2.2 效果展示
從 10 開(kāi)始計(jì)數(shù)

直到變成 0 為止。
?2.3 注意事項(xiàng): 每打印一個(gè)數(shù)字后緊跟著打印一個(gè) 回車,讓光標(biāo)回到這一行最開(kāi)始的位置,這樣新打印的數(shù)字就會(huì)去覆蓋掉老的數(shù)字。但是 不會(huì)去刷新緩沖區(qū),因此在每打印完一個(gè)數(shù)字后,需要調(diào)用fflush(stdout)來(lái)刷新緩沖區(qū)。 這里我們需要知道,往顯示器上打印整型10,本質(zhì)上是打印了字符1和字符0,由于這兩個(gè)字符是挨在一起的,我們看起來(lái)就像是整型10。因此打印10,會(huì)占用兩個(gè)字符,而打印0~9只需要一個(gè)字符,所以 回車之后去覆蓋寫(xiě),只會(huì)覆蓋一個(gè)字符,對(duì)第二個(gè)字符0始終沒(méi)有影響,因此我們需要用%-2d來(lái)控制,每次打印兩個(gè)位寬的字符,-表示將這兩個(gè)字符左對(duì)齊。如果不進(jìn)行格式化控制,打印出來(lái)的結(jié)果將是下面這樣:

?三、進(jìn)度條?3.1 源代碼?processBar.h代碼語(yǔ)言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制
#pragma once#include <stdio.h>#define NUM 102#define STYLE '=' #define TOP 100#define BODY '$'extern void processbar();</stdio.h>
?processBar.c代碼語(yǔ)言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制
#include "processBar.h"#include <string.h>#include <unistd.h>const char* lable = "|/-";//旋轉(zhuǎn)提示void processbar(){ char bar[NUM]; memset(bar, ' 主站蜘蛛池模板: 日本一区二区三区在线 视频观看免费 | 日韩免费高清一级毛片在线 | 在线视频1区 | 三级黄色片在线免费观看 | 特黄特色一级特色大片中文 | 四虎影视永久在线 yin56xyz | 四虎国产精品永久免费网址 | 欧美一级特黄做 | 色狠狠一区| 亚洲综合久久伊人热 | 亚洲伊人久久大香线蕉综合图片 | 在线观看视频一区二区三区 | 国产成人综合洲欧美在线 | 国产成人拍精品视频网 | 一级不卡毛片免费 | 黄色网址国产 | 综合久久精品 | 亚洲国产精品嫩草影院 | 色偷偷人人澡人人爽人人模 | 欧美与黑人午夜性猛交久久久 | 久久99精品久久久久久野外 | 伊人网在线视频观看 | 久久高清免费视频 | 日日拍夜夜嗷嗷叫国产 | 一区二区三区久久精品 | www五月| 亚洲成 人a影院青久在线观看 | 狠狠躁夜夜躁人人躁婷婷视频 | 色综合合久久天天给综看 | 日韩亚洲制服丝袜中文字幕 | 亚洲最大中文字幕 | 亚洲丁香婷婷综合久久六月 | 国产精品亚洲玖玖玖在线靠爱 | 在线毛片网| 欧美日韩国产码高清综合人成 | 日本一区二区三区在线观看 | 欧美成人亚洲国产精品 | 亚洲色图欧美视频 | 天天干b | 亚色成人| 日韩欧国产精品一区综合无码 |