C語言學(xué)習(xí)筆記(二):字符串和格式化輸入/輸出

本章的主題是C語言的字符串和格式化輸入/輸出。


  1. C語言沒有專門用于存儲(chǔ)字符串的變量類型吗跋,字符串都被存儲(chǔ)在char類型的數(shù)組中桌粉。

  2. 數(shù)組是同類型數(shù)據(jù)元素的有序序列。

    • char name[40]為例祭钉,name后面的方括號表明這是一個(gè)數(shù)組,方括號中的40表明該數(shù)組中的元素?cái)?shù)量己沛,char表明每個(gè)元素的類型慌核。
    • 字符串可以理解為字符數(shù)組,每個(gè)單元存儲(chǔ)一個(gè)字符申尼,數(shù)組末尾用一個(gè)空字符(null character)標(biāo)識結(jié)束遂铡。
  3. 空字符\0是非打印字符,其ASCII碼值為0晶姊。由于空字符的存在,因此字符串實(shí)際能存儲(chǔ)的字符數(shù)要減1伪货,剩下一個(gè)字節(jié)留給空字符们衙。上例中字符串name實(shí)際能存儲(chǔ)的字符數(shù)為39钾怔。

  4. 轉(zhuǎn)換字符%s用于讀寫字符串,%zd用于處理sizeof()strlen()的返回值蒙挑。

  5. scanf()在遇到第一個(gè)空白(空格宗侦、制表符或換行符)時(shí)就不再讀取輸入。C語言還有其他的輸入函數(shù)(如忆蚀,fgets())矾利,用于讀取一般字符串,后面會(huì)詳談馋袜。

  6. 使用符號常量(symbolic constant)明示常量(manifest constant)的好處:

    • 常量名比數(shù)字表達(dá)的信息更多男旗;
    • 復(fù)用性更好。
  7. 使用C預(yù)處理器來定義符號常量:#define NAME value欣鳖。

    • 例如察皇,#define PI 3.14159。編譯程序時(shí)泽台,程序中所有的PI都會(huì)被替換成3.14159什荣。這一過程被稱為編譯時(shí)替換(compile-time substitution)
    • 為什么PI要大寫怀酷?因?yàn)橛么髮懕硎痉柍A渴荂語言一貫的傳統(tǒng)稻爬,這樣做是為了提高程序的可讀性,在程序中看到全大寫的名稱就立刻明白這是一個(gè)符號常量蜕依,而非變量桅锄。
  8. C90標(biāo)準(zhǔn)新增了const關(guān)鍵字,用于限定一個(gè)變量為只讀笔横。

    const int MONTHS = 12;    // MONTHS在程序中不可更改竞滓,值為12
    

    const用起來比#define更靈活,后續(xù)會(huì)詳談吹缔。

  9. printf()scanf()是標(biāo)準(zhǔn)輸入/輸出函數(shù)商佑,簡稱為I/O函數(shù)。printf()把整數(shù)厢塘、浮點(diǎn)數(shù)茶没、字符和字符串轉(zhuǎn)換成顯示在屏幕上的文本,而scanf()正好與它相反晚碾,把輸入的字符串轉(zhuǎn)換成整數(shù)抓半、浮點(diǎn)數(shù)、字符和字符串存儲(chǔ)在內(nèi)存中格嘁。

  10. printf()的格式為:printf(格式字符串, 待打印項(xiàng)1, 待打印項(xiàng)2, ...)
    其中笛求,格式字符串是雙引號括起來的內(nèi)容,包含兩種形式不同的信息:(1)實(shí)際要打印的字符;(2)轉(zhuǎn)換說明探入。待打印項(xiàng)1狡孔、待打印項(xiàng)2等都是要打印的項(xiàng),可以是變量蜂嗽、常量或表達(dá)式苗膝。

  11. printf()的轉(zhuǎn)換說明

轉(zhuǎn)換說明 含義
%a 浮點(diǎn)數(shù)、十六進(jìn)制數(shù)和p記數(shù)法(C99/C11)
%A 浮點(diǎn)數(shù)植旧、十六進(jìn)制數(shù)和p記數(shù)法(C99/C11)
%c 單個(gè)字符
%d 有符號十進(jìn)制整數(shù)
%e 浮點(diǎn)數(shù)辱揭,e記數(shù)法
%E 浮點(diǎn)數(shù),e記數(shù)法
%f 浮點(diǎn)數(shù)病附,十進(jìn)制記數(shù)法
%g 根據(jù)值的不同问窃,自動(dòng)選擇%f%e
%G 根據(jù)值的不同胖喳,自動(dòng)選擇%f%E泡躯。
%i 有符號十進(jìn)制整數(shù)(和%d相同)
%o 無符號八進(jìn)制整數(shù)
%p 指針
%s 字符串
%u 無符號十進(jìn)制整數(shù)
%x 無符號十六進(jìn)制整數(shù),使用十六進(jìn)制數(shù)0f
%X 無符號十六進(jìn)制整數(shù)丽焊,使用十六進(jìn)制數(shù)0F
%% 打印一個(gè)百分號
  1. printf()的轉(zhuǎn)換說明修飾符:在%轉(zhuǎn)換字符之間插入修飾符可修飾基本的轉(zhuǎn)換說明较剃。
修飾符 含義
標(biāo)記 ????????? 有6種標(biāo)記(-+技健、空格写穴、#*0)雌贱,可以不使用標(biāo)記或使用多個(gè)標(biāo)記

-:待打印項(xiàng)左對齊

+:有符號值若為正啊送,則在值前面顯示加號;若為負(fù)欣孤,則在值前面顯示減號

空格:有符號值若為正馋没,則在值前面顯示前導(dǎo)空格;若為負(fù)降传,則在值前面顯示減號

#:把結(jié)果轉(zhuǎn)換為另一種類型篷朵。如果是%o格式,則以0開始婆排;如果是%x%X格式声旺,則以0x0X開始;對于所有的浮點(diǎn)格式段只,#保證了即使后面沒有任何小數(shù)腮猖,也打印一個(gè)小數(shù)點(diǎn)字符;對于%g%G格式赞枕,#防止結(jié)果后面的0被刪除

*:抑制賦值(詳見后面解釋)

0:對于數(shù)值格式澈缺,用前導(dǎo)0代替空格填充字段寬度坪创。對于整型格式,如果出現(xiàn)-標(biāo)記或指定精度姐赡,則忽略該標(biāo)記 ?
數(shù)字 最小字段寬度
如果該字段不能容納待打印的數(shù)字或字符串误堡,系統(tǒng)會(huì)使用更寬的字段
.數(shù)字 精度
對于%e%E%f轉(zhuǎn)換雏吭,表示小數(shù)點(diǎn)右邊數(shù)字的位數(shù)
對于%s轉(zhuǎn)換,表示待打印字符的最大數(shù)量
對于整型轉(zhuǎn)換陪踩,表示待打印數(shù)字的最小位數(shù)
如有必要杖们,使用前導(dǎo)0來達(dá)到這個(gè)位數(shù)
只使用.表示其后跟隨一個(gè)0,所以%.f%.0f相同
h 和整型轉(zhuǎn)換說明一起使用肩狂,表示short intunsigned short int類型的值
hh 和整型轉(zhuǎn)換說明一起使用摘完,表示signed charunsigned char類型的值
j 和整型轉(zhuǎn)換說明一起使用,表示intmax_tuintmax_t類型的值傻谁。這些類型定義在stdint.h
l 和整型轉(zhuǎn)換說明一起使用孝治,表示long intunsigned long int類型的值
ll 和整型轉(zhuǎn)換說明一起使用,表示long long intunsigned long long int類型的值
L 和浮點(diǎn)轉(zhuǎn)換說明一起使用审磁,表示long double類型的值
t 和整型轉(zhuǎn)換說明一起使用谈飒,表示ptrdiff_t類型的值。ptrdiff_t是兩個(gè)指針差值的類型
z 和整型轉(zhuǎn)換說明一起使用态蒂,表示size_t類型的值杭措。size_tsizeof()返回的類型
  1. printf()有一個(gè)返回值,它返回打印字符的個(gè)數(shù)钾恢。如果有輸出錯(cuò)誤手素,則返回一個(gè)負(fù)值。

  2. 給字符串?dāng)嘈杏?種方法瘩蚪。

// longstrg.c --打印較長的字符串
#include <stdio.h>

int main(void)
{
    // 方法1:使用多個(gè)printf()語句
    printf("Here's one way to print a ");
    printf("long string.\n");

    // 方法2:使用反斜杠和Enter鍵組合
    printf("Here's another way to print a \
long string.\n");

    // 方法3:字符串連接
    printf("Here's the newest way to print a "
            "long string.\n");

    return 0;
 }
  1. scanf()函數(shù)的格式為:scanf(格式字符串, 地址列表)
    其中泉懦,地址列表是指向變量的指針,此處不必了解如何使用指針疹瘦,只需記住以下兩條簡單的規(guī)則:

    • 如果用scanf()讀取基本變量類型的值崩哩,則在變量名前加上一個(gè)&
    • 如果用scanf()把字符串讀入字符數(shù)組中拱礁,不要使用&琢锋。
  2. scanf()函數(shù)所用的轉(zhuǎn)換說明與printf()函數(shù)幾乎相同。主要的區(qū)別是呢灶,對于float類型和double類型吴超,printf()都使用%f%e鸯乃、%E鲸阻、%g%G轉(zhuǎn)換說明跋涣,而scanf()只把它們用于float類型,對于double類型要用l修飾符鸟悴。

  3. scanf()中陈辱,除了%c,其他轉(zhuǎn)換說明都會(huì)自動(dòng)跳過待輸入值前面的所有空白细诸。

  4. scanf()函數(shù)允許把普通字符放在格式字符串中沛贪。除空格字符外的普通字符必須與輸入字符串嚴(yán)格匹配

  5. scanf()函數(shù)返回成功讀取的項(xiàng)數(shù)震贵。如果沒有讀取任何項(xiàng)利赋,且需要讀取一個(gè)數(shù)字而用戶卻輸入一個(gè)非數(shù)值字符串,scanf()便返回0猩系。

  6. printf()scanf()都可以使用*修飾符來修改轉(zhuǎn)換說明的含義媚送,但用法不一樣。

    • printf():如果不想預(yù)先指定字段寬度或精度寇甸,希望通過程序來指定塘偎,可以用*修飾符代替字段寬度或精度,但需要參數(shù)告訴函數(shù)拿霉,字段寬度或精度應(yīng)該是多少吟秩。
    • scanf():把*放在%和轉(zhuǎn)換字符之間時(shí),會(huì)使得scanf()跳過相應(yīng)的輸入項(xiàng)友浸。在程序需要讀取文件中特定列的內(nèi)容時(shí)峰尝,這項(xiàng)跳過功能很有用。
  7. 使用scanf()輸入分?jǐn)?shù)時(shí)收恢,不能直接使用以下語句

/* 這是錯(cuò)誤的分?jǐn)?shù)輸入 */
scanf("%f", &x);    // 在實(shí)際輸入的時(shí)候不能輸入類似"3/7"的數(shù)值武学,因?yàn)閟canf()并不能識別"/"

/* 這是正確的分?jǐn)?shù)輸入 */
scanf("%d/%d", &x, &y);
  1. 使用scanf()可以實(shí)現(xiàn)長數(shù)據(jù)的截取與跳過
/* 截取身份證號的出生年月日 */
#include <stdio.h>

int main(void)
{
    int year, month, day;
    
    printf("請輸入您的身份證號:");
    scanf("%*6d%4d%2d%2d%*4d", &year, &month, &day);

    printf("您的生日是:%d年%d月%d日\n", year, month, day);

    return 0;
 }

下一章的主題是C語言的運(yùn)算符、表達(dá)式和語句伦意。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末火窒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子驮肉,更是在濱河造成了極大的恐慌熏矿,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件离钝,死亡現(xiàn)場離奇詭異票编,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)卵渴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門慧域,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浪读,你說我怎么就攤上這事昔榴⌒猎澹” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵互订,是天一觀的道長吱肌。 經(jīng)常有香客問我,道長仰禽,這世上最難降的妖魔是什么氮墨? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮吐葵,結(jié)果婚禮上勇边,老公的妹妹穿的比我還像新娘。我一直安慰自己折联,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布识颊。 她就那樣靜靜地躺著诚镰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祥款。 梳的紋絲不亂的頭發(fā)上清笨,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機(jī)與錄音刃跛,去河邊找鬼抠艾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛桨昙,可吹牛的內(nèi)容都是我干的检号。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼蛙酪,長吁一口氣:“原來是場噩夢啊……” “哼齐苛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起桂塞,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凹蜂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后阁危,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玛痊,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年狂打,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了擂煞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡菱父,死狀恐怖颈娜,靈堂內(nèi)的尸體忽然破棺而出剑逃,到底是詐尸還是另有隱情,我是刑警寧澤官辽,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布蛹磺,位于F島的核電站,受9級特大地震影響同仆,放射性物質(zhì)發(fā)生泄漏萤捆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一俗批、第九天 我趴在偏房一處隱蔽的房頂上張望俗或。 院中可真熱鬧,春花似錦岁忘、人聲如沸辛慰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帅腌。三九已至,卻和暖如春麻汰,著一層夾襖步出監(jiān)牢的瞬間速客,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工五鲫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溺职,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓位喂,卻偏偏與公主長得像浪耘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子塑崖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

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