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

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

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

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

[復(fù)制鏈接]

454

主題

454

帖子

3643

積分

四級(jí)會(huì)員

Rank: 4

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

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

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

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

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

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

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


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

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

本版積分規(guī)則


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