自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于C++遍歷中文字符串的問(wèn)題

開發(fā)
今天來(lái)介紹一個(gè)C++中的基礎(chǔ)問(wèn)題:中文字符串的遍歷問(wèn)題。首先我們來(lái)一個(gè)demo,假如要使用std::string遍歷"你好,世界123"這個(gè)字符串,你會(huì)怎么寫?

今天來(lái)介紹一個(gè)C++中的基礎(chǔ)問(wèn)題:中文字符串的遍歷問(wèn)題。可就是這么的一個(gè)基礎(chǔ)問(wèn)題,也坑了我不少時(shí)間,真是應(yīng)了那句話基礎(chǔ)不牢,地動(dòng)山搖。

小試牛刀

首先我們來(lái)一個(gè)demo,假如要使用std::string遍歷"你好,世界123"這個(gè)字符串,你會(huì)怎么寫?

當(dāng)時(shí)筆者是這么想的:

于是大手一揮,Ctrl C + Ctrl V寫下了一下代碼:

using namespace std;
int main() {
    std::string text = "你好,世界123";
    for (const auto c:text) {
        std::cout << "c:" << c << std::endl;
    }
    return 0;
}

運(yùn)行起來(lái)一看,我都懵逼了,居然是亂碼...

一看到亂碼,筆者首先想到的可能編碼不是utf-8的,于是我改了一行代碼:

 std::string text = u8"你好,世界123";

結(jié)果還是于事無(wú)補(bǔ),還是亂碼的,我開始有點(diǎn)慌了...

在這里說(shuō)明一下當(dāng)在C++中使用字符串字面值時(shí),可以使用前綴u8來(lái)表示使用UTF-8編碼。這意味著該字符串會(huì)以UTF-8編碼的格式存儲(chǔ)在內(nèi)存中。

面對(duì)這些亂碼,我不得不拿出CV工程師的殺手锏,趕緊上stackoverflow求助...

不負(fù)眾望,果然被我找到了答案。。。

馬上復(fù)制粘貼來(lái)驗(yàn)證一波...

using namespace std;
int main() {
    std::string text = u8"你好,世界123";
    for(size_t i = 0; i < text.length();)
    {
        int cplen = 1;
        if((text[i] & 0xf8) == 0xf0) cplen = 4;
        else if((text[i] & 0xf0) == 0xe0) cplen = 3;
        else if((text[i] & 0xe0) == 0xc0) cplen = 2;
        if((i + cplen) > text.length()) cplen = 1;
        cout << text.substr(i, cplen) << endl;
        i += cplen;
    }
    return 0;
}

運(yùn)行起來(lái),果然是想要的結(jié)果。666,憑實(shí)力攻克了一個(gè)技術(shù)難題,帶領(lǐng)公司往前跨了一大步,這回升級(jí)加薪穩(wěn)了吧!!!

尋根問(wèn)底

本著舉一反三的學(xué)習(xí)態(tài)度,我想知道為什么中文字符串的遍歷要特殊處理,我找到了這個(gè):https://en.wikipedia.org/wiki/UTF-8#Description

原來(lái)一個(gè)中文字符不一定是和英文一樣占用一個(gè)字符,它們可能會(huì)占用幾個(gè)字符,但它們的長(zhǎng)度其實(shí)可以從字符的頭中讀取出來(lái)的。

我簡(jiǎn)單地用瀏覽器翻譯了一下,大家將就這看一下大概意思

當(dāng)然如果你不想自己寫獲取中文字符長(zhǎng)度的邏輯代碼,也可以用別人寫好的開源庫(kù)。這里給大家推薦一個(gè)輕量級(jí)的,只有一個(gè)utf8.h文件的開源庫(kù):https://github.com/sheredom/utf8.h

那么我們的代碼就變成了這樣:

int main() {
    std::string text = u8"你好,世界123";
    for (size_t i = 0; i < text.size();)
    {
        auto cplen = utf8codepointcalcsize(&text[i]);
        std::cout << text.substr(i, cplen) << std::endl;
        i += cplen;
    }
    return 0;
}

其實(shí)我們查看下utf8.h這個(gè)庫(kù)的utf8codepointcalcsize函數(shù)內(nèi)部實(shí)現(xiàn),和我們上面說(shuō)的是一樣的。

這么一個(gè)簡(jiǎn)單的坑,以前怎么沒(méi)發(fā)現(xiàn)這個(gè)問(wèn)題?一個(gè)是沒(méi)遇到過(guò)這樣的需求,二是就算用到了也不是用C++實(shí)現(xiàn)的,例如在QT上直接使用QString就沒(méi)有這些問(wèn)題。

責(zé)任編輯:趙寧寧 來(lái)源: 思想覺(jué)悟
相關(guān)推薦

2011-06-16 17:01:21

Qt MeeGo 排序

2010-02-02 16:49:32

C++中文字符

2009-11-26 16:26:32

PHP字符串mbstr

2009-11-26 16:43:11

PHP截取中文字符串

2021-09-07 09:23:07

C++字符串算法

2009-12-01 15:41:16

PHP substr截

2010-03-05 16:09:44

Python中文字符

2010-02-02 11:27:16

C++字符串

2010-02-05 09:57:25

C++中英文字符串

2011-07-18 13:34:44

SQL Server數(shù)拼接字符串

2023-12-11 15:18:03

C++字符串Unicode

2010-02-04 17:39:48

C++字符串類型

2021-07-30 06:22:37

C++字符型字符串

2009-11-27 09:55:11

PHP截取中文字符

2010-02-04 17:32:43

C++中C風(fēng)格字符串

2024-02-22 09:46:04

C++字符串格式化開發(fā)

2021-08-20 06:58:31

C++Python函數(shù)

2010-02-02 18:01:47

C++字符串替換函數(shù)

2009-11-27 09:30:58

PHP函數(shù)mb_str

2010-02-01 16:46:07

C++格式化字符串
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)