09 重憶C之 字符串

在之前的學(xué)習(xí)中简识,我們?cè)?jīng)使用過printf函數(shù)對(duì)字符串進(jìn)行輸出。那么感猛,如果我們希望輸入一個(gè)字符串到變量七扰,我們可以怎么做呢?

第一種:scanf陪白。
希望接收一個(gè)字符串到string這個(gè)變量戳寸。可以使用scanf("%s", string);這里寫的并不是&string而是string拷泽。因?yàn)樵?C 語言中,數(shù)組名直接可以被當(dāng)做數(shù)組所在內(nèi)存的地址使用袖瞻。輸出的時(shí)候可以使用printf("%s\n");來輸出
對(duì)于如下代碼:

#include <stdio.h>
int main() {
    char string[10];
    // 請(qǐng)?jiān)谶@里使用 scanf
    scanf("%s", string);
    printf("%s\n",string);
    return 0;
}

點(diǎn)擊 運(yùn)行 測(cè)試一下程序司致,看看如果你輸入hello worlditisverylongforittostore分別會(huì)有怎樣的結(jié)果聋迎?

當(dāng)輸入hello world時(shí)脂矫,被輸出的只有hello。這是因?yàn)?code>scanf在遇到空格時(shí)就已經(jīng)終止讀入了霉晕。

當(dāng)輸入一個(gè)很長的字符串時(shí)庭再,就出現(xiàn)了 Segmentation Fault(段錯(cuò)誤)。因?yàn)槁暶鞯淖址麛?shù)組長度只有 10牺堰,我們已經(jīng)在程序運(yùn)行時(shí)拄轻,讓它寫入了“不屬于它”的內(nèi)存空間。

來看看第二種:

嵌入占位符

#include <stdio.h>

int main() {
    char information[100];
    char *name = "Li, Lei";
    char *gender = "male";
    int age = 14;
    float height = 187.5f;
    // 在這里使用 sprintf
    sprintf(information, "%s is a %s. He is %d-year-old and %fcm tall.", name, gender, age, height);
    printf("%s", information);
}

輸出為
Li, Lei is a male. He is 14-year-old and 187.500000cm tall.

sprintfinformation這一字符串中寫入了一個(gè)格式化輸出的結(jié)果伟葫,依照字符串格式描述恨搓,一系列intfloat等類型的數(shù)據(jù)被“嵌入”到了格式字符串的占位符位置,并最終寫入到了information中斧抱。
即將一系列的變量按照指定格式寫入到一個(gè)字符串中常拓。

sprintf可用于各種數(shù)據(jù)的格式化:

  • 第一個(gè)參數(shù)是被寫入的字符串;
  • 第二個(gè)參數(shù)是寫入的格式;
  • 之后的參數(shù)是依次會(huì)被寫入的數(shù)據(jù)。

在這里要提醒一下辉浦,我們一定要注意用于第一個(gè)參數(shù)的字符串聲明時(shí)的長度弄抬,如果它所對(duì)應(yīng)的內(nèi)存空間不足,我們現(xiàn)在的這種用法就可能會(huì)觸發(fā)段錯(cuò)誤宪郊。

字符串長度

頭文件#include <string.h>
使用方法:

strlen(字符串字面量或者變量)    //返回得到的是其長度(不帶末位\0)

復(fù)制字符串

strcpy(copy, string);       //第二個(gè)參數(shù)是被復(fù)制的字符串掂恕,第一個(gè)參數(shù)是需要復(fù)制到的目標(biāo)字符串變量位置

在程序中通過strcpy完成了復(fù)制的過程后,copy中就和string中的字符串是一致的了废膘。

要注意一下竹海,在使用strcpy時(shí)要確保目標(biāo)字符串的聲明長度可以裝得下,否則程序運(yùn)行時(shí)則可能會(huì)出現(xiàn)段錯(cuò)誤丐黄。

為避免此問題斋配,在工程中更多的鼓勵(lì)使用增加了第三個(gè)“復(fù)制長度”參數(shù)的strncpy函數(shù)。即只把前n個(gè)字符復(fù)制上去灌闺。

字符串的字典序(比較)

在數(shù)學(xué)中諸如 10 < 20這樣數(shù)字的大小關(guān)系是天然定義的艰争,可是對(duì)于字符、字符串來說桂对,他們有“大小”關(guān)系嗎甩卓?

當(dāng)我們把"China"和"America"放在一起的時(shí)候,我們可以說它們這兩個(gè)字符串其中有一個(gè)大于另外一個(gè)么蕉斜?這個(gè)問題的回答是——“有”逾柿。

C 語言中對(duì)于字符的比較依賴的是字符的編碼,C 語言中默認(rèn)使用了 ASCII(American Standard Code for Information Interchange宅此,美國標(biāo)準(zhǔn)信息交換碼)作為編碼標(biāo)準(zhǔn)机错,每一個(gè)字符都對(duì)應(yīng)了一個(gè)整數(shù)值。常見的一些字符和他們對(duì)應(yīng)的編碼值如下:

ASCII碼

通過參考列出的 ASCII 碼參考表(局部)父腕,在 C 語言中弱匪,字符直接進(jìn)行大小的比較時(shí),會(huì)對(duì)它們的編碼值進(jìn)行比較璧亮。因此萧诫,'A'小于'B','A'小于'a'枝嘶。

C 語言中帘饶,通常遵循一種特殊定義——字典序(lexicographical order)。
說白了就是后面的比前面的大群扶,有比沒有大尖奔。
"abc" < "bbc"

  • 對(duì)于字符串"abc""bbc"的大小關(guān)系——
    我們首先會(huì)對(duì)它們的第一個(gè)字符進(jìn)行比較,
    我們發(fā)現(xiàn)第一個(gè)字符'a'< 'b'時(shí),
    我們就可以明確"abc" <"bbc"的結(jié)論提茁。

"abc" < "abd"

  • 對(duì)于字符串"abc""abd"的大小關(guān)系——
    我們首先會(huì)對(duì)它們的第一個(gè)字符進(jìn)行比較淹禾,
    如果第一個(gè)字符相同,則會(huì)接下來比較第二個(gè)字符茴扁;
    如果第二個(gè)字符相同铃岔,則會(huì)接下來比較第三個(gè)字符,
    當(dāng)我們發(fā)現(xiàn)第三個(gè)字符'c'<'d'時(shí)峭火,我們就得到了"abc"< "abd"的結(jié)論毁习。

"ab" < "abc"

  • 對(duì)于字符串"abc""ab"的大小關(guān)系——
    我們首先會(huì)對(duì)它們的第一個(gè)字符進(jìn)行比較,
    如果第一個(gè)字符相同卖丸,則會(huì)接下來比較第二個(gè)字符纺且;
    如果第二個(gè)字符相同,則會(huì)接下來比較第三個(gè)字符稍浆,
    當(dāng)我們發(fā)現(xiàn)"ab"沒有第三個(gè)字符時(shí)载碌,我們就得到了"ab"< "abc"的結(jié)論嵌牺。

總結(jié):

  • 字典序遵循 逐字符比較的方式胸哥,越靠左的字符越會(huì)被先比較策精。
  • 逐字符比較過程中腰耙,一旦發(fā)現(xiàn)某一對(duì)被比較的字符之間不相等時(shí),這一對(duì)字符的大小關(guān)系即為這一對(duì)字符串的大小關(guān)系艇潭。
  • 逐字符比較過程中侣诺,一旦出現(xiàn)某一個(gè)字符串的所有字符都已經(jīng)經(jīng)過比較拳锚,而另一字符串還存在未被比較的字符時(shí)益楼,較短的字符串更小猾漫。
  • 如果所有字符串內(nèi)的字符都被發(fā)現(xiàn)相等,則這兩個(gè)字符串相等感凤。
    因此悯周,字符串"China"大于"America"。

比較的語句 strcmp(input, string);

input小于string時(shí)返回了負(fù)數(shù)俊扭,當(dāng)input等于string時(shí)返回了 0,當(dāng)input大于string時(shí)返回正數(shù)呢坠陈?

我們可以通過在if的條件中寫:
strcmp(input, string) == 0
來判斷兩個(gè)字符串是否相同萨惑。也可以將等號(hào)改為大于號(hào)、小于號(hào)來判斷字符串的大小關(guān)系仇矾。

問題:

輸入 10行不含有空格的字符串庸蔼,對(duì)應(yīng)十個(gè)學(xué)生姓名(長度大于 0 小于 20)。
輸出為 101行贮匕,為排序后的 10 個(gè)學(xué)生姓名姐仅,每個(gè)學(xué)生姓名單獨(dú)占一行。

樣例輸入

Alice
Bob
Gary
Harry
Ivn
Julia
Danis
Fone
Candy
Evan

樣例輸出

Alice
Bob
Candy
Danis
Evan
Fone
Gary
Harry
Ivn
Julia

代碼

#include <stdio.h>
#include <string.h>
void swap(char a[20], char b[20]){
    char c[20];
    strcpy(c, a);
    strcpy(a, b);
    strcpy(b, c);
}
int main() {
    char arr[10][20];
    int i,j;
    for (i = 0; i < 10; i++){
        scanf("%s",arr[i]);
    }
    for (i = 0; i < 10; i++ ){
        for (j = 0; j < 9; j++){
            if (strcmp(arr[j],arr[j+1])>0){
                swap(arr[j],arr[j+1]);
            }
        }
    }
    for (i = 0; i < 10; i++){
        printf("%s\n",arr[i]);
    }
}

字符串拼接

strcat(A, B);會(huì)把參數(shù)的第二個(gè)字符串(含\0)加在第一個(gè)字符串的/0位置
strcat函數(shù)將第二個(gè)參數(shù)的字符串(含\0)拷貝到第一個(gè)參數(shù)的字符串\0所在內(nèi)存位置及之后。所以掏膏,我們通過

strcat(hello, world);
就會(huì)改變hello的值劳翰,讓"hello "之后多出了"world"這段字符串
(假設(shè)char hello[100] = "hello "; char world[100] = "world";)。

類似于strcpy函數(shù)馒疹,在使用strcat函數(shù)時(shí)佳簸,也要注意內(nèi)存安全問題。如果被連接上新內(nèi)容的目標(biāo)字符串的聲明長度不夠長颖变,程序就可能出錯(cuò)生均。相應(yīng)工程中也更鼓勵(lì)使用增加了第三個(gè)“追加長度”參數(shù)的strncat函數(shù),即只把前n個(gè)字符拼上去腥刹。大家可以通過搜索引擎具體了解一下马胧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市衔峰,隨后出現(xiàn)的幾起案子佩脊,更是在濱河造成了極大的恐慌,老刑警劉巖朽色,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邻吞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡葫男,警方通過查閱死者的電腦和手機(jī)抱冷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梢褐,“玉大人旺遮,你說我怎么就攤上這事∮龋” “怎么了耿眉?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鱼响。 經(jīng)常有香客問我鸣剪,道長,這世上最難降的妖魔是什么丈积? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任筐骇,我火速辦了婚禮,結(jié)果婚禮上江滨,老公的妹妹穿的比我還像新娘铛纬。我一直安慰自己,他們只是感情好唬滑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布告唆。 她就那樣靜靜地躺著棺弊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪擒悬。 梳的紋絲不亂的頭發(fā)上模她,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音茄螃,去河邊找鬼缝驳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛归苍,可吹牛的內(nèi)容都是我干的用狱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼拼弃,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼夏伊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吻氧,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤溺忧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后盯孙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲁森,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年振惰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歌溉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骑晶,死狀恐怖痛垛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桶蛔,我是刑警寧澤匙头,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站仔雷,受9級(jí)特大地震影響蹂析,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碟婆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一电抚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脑融,春花似錦喻频、人聲如沸缩宜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至妓布,卻和暖如春姻蚓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匣沼。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工狰挡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人释涛。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓加叁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唇撬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子它匕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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

  • 作者 謝恩銘,公眾號(hào)「程序員聯(lián)盟」(微信號(hào):coderhub)窖认。轉(zhuǎn)載請(qǐng)注明出處豫柬。原文:https://www.ji...
    程序員聯(lián)盟閱讀 2,404評(píng)論 3 33
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)扑浸,斷路器烧给,智...
    卡卡羅2017閱讀 134,633評(píng)論 18 139
  • 一、字符串操作 strcpy(p, p1) 復(fù)制字符串 strncpy(p, p1, n) 復(fù)制指定長度字符串 s...
    JaiUnChat閱讀 1,655評(píng)論 0 7
  • 莫不過 是走不出自己 跌在了坑里 卻自己 把坑挖的越深 直至雙手沾了紅 還是不知疼惜 也曾深深懷疑 深...
    夏小時(shí)閱讀 172評(píng)論 0 0
  • 緣起:明明德于天下 《大學(xué)》喝噪,在我大學(xué)畢業(yè)之前础嫡,與它都沒有任何連接,大概是讀研究生時(shí)仙逻,本科的同學(xué)給我發(fā)過一個(gè)消息問...
    止弌閱讀 356評(píng)論 0 1