電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 38|回復(fù): 0
收起左側(cè)

如何正確地將字符串轉(zhuǎn)換為大寫或小寫?

[復(fù)制鏈接]

445

主題

445

帖子

3456

積分

四級會員

Rank: 4

積分
3456
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-11-3 15:01:00 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
微博@量子位
鏈接:https://weibo.com/6105753431/OAKGOdAww
#字符串大小寫轉(zhuǎn)換正確方法#
最近,微軟大神 Raymond Chen 分享了一個在 C++ 編程中常見,但又容易被弄錯的問題:如何正確地將字符串轉(zhuǎn)換為大寫或小寫。
比如,當(dāng)你開發(fā)一個應(yīng)用程序時,需要將字符串轉(zhuǎn)為小寫形式。于是,你寫下了的代碼。

乍看之下,使用 STL 的 std::transform 和 std::tolower 沒什么問題,事實(shí)上卻踩了三個坑:
1、std::tolower 不能直接使用
由于 std::tolower 并不是一個可尋址的函數(shù),因此不能直接作為函數(shù)指針傳遞給 std::transform,需要改為:

2、字符類型匹配問題
眾所周知,std::tolower 只適用于 unsigned char 范圍內(nèi)的字符,如果字符串中有非 ASCII 字符,比如中文、日文、韓文或特殊符號,以及寬字符字符串 std::wstring,std::tolower 都無法正確處理,甚至可能導(dǎo)致未定義行為。
因此,需要用到 std::towlower 但這仍然有問題,因為它無法正確處理 UTF-16 編碼中的代理對(surrogate pairs),也就是那些需要兩個 wchar_t 來表示的字符。

3、字符長度變化
有些字符在轉(zhuǎn)換大小寫后,長度會發(fā)生變化。舉個例子:
? 德語的特殊字符 “?” (U+00DF),轉(zhuǎn)換成大寫后變成了 “SS”,長度從 1 變成了 2。
? 合字字符,如拉丁小寫連字 “?” (U+FB02),轉(zhuǎn)換成大寫后變成兩個字符 “FL”。
? 在某些語言中,字符轉(zhuǎn)換大小寫后可能會消失或新增。
逐字符轉(zhuǎn)換無法處理上述這些情況,會導(dǎo)致字符串截斷或數(shù)據(jù)損壞。
那么,正確的姿勢是什么?
要正確地進(jìn)行字符串大小寫轉(zhuǎn)換,應(yīng)該使用能夠全面處理 Unicode 的函數(shù):
1、 Windows 平臺:使用 LCMapStringEx 函數(shù):

2.、跨平臺解決方案:使用 ICU(International Components for Unicode)庫:

感興趣的小伙伴可以閱讀原帖:https://devblogs.microsoft.com/oldnewthing/20241007-00/?p=110345——EOF——你好,我是飛宇。日常分享C/C++、計算機(jī)學(xué)習(xí)經(jīng)驗、工作體會,歡迎點(diǎn)擊此處查看我以前的學(xué)習(xí)筆記&經(jīng)驗&分享的資源。
我組建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起進(jìn)群交流。

歡迎你添加我的微信,我拉你進(jìn)技術(shù)交流群。此外,我也會經(jīng)常在微信上分享一些計算機(jī)學(xué)習(xí)經(jīng)驗以及工作體驗,還有一些內(nèi)推機(jī)會。


加個微信,打開另一扇窗
經(jīng)常遇到有讀者后臺私信想要一些編程學(xué)習(xí)資源,這里分享 1T 的編程電子書、C/C++開發(fā)手冊、Github上182K+的架構(gòu)路線圖、LeetCode算法刷題筆記等精品學(xué)習(xí)資料,點(diǎn)擊下方公眾號會回復(fù)"編程"即可免費(fèi)領(lǐng)取~
感謝你的分享,點(diǎn)贊,在看三  

回復(fù)

使用道具 舉報

發(fā)表回復(fù)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表