电子产业一站式赋能平台

PCB联盟网

搜索
查看: 126|回复: 0
收起左侧

如何正确地将字符串转换为大写或小写?

[复制链接]

498

主题

498

帖子

4895

积分

四级会员

Rank: 4

积分
4895
发表于 2024-11-3 15:01:00 | 显示全部楼层 |阅读模式
微博@量子位
链接:https://weibo.com/6105753431/OAKGOdAww
#字符串大小写转换正确方法#
最近,微软大神 Raymond Chen 分享了一个在 C++ 编程中常见,但又容易被弄错的问题:如何正确地将字符串转换为大写或小写。
比如,当你开发一个应用程序时,需要将字符串转为小写形式。于是,你写下了的代码。

hbj0fc5qcyz64090170716.png

hbj0fc5qcyz64090170716.png

乍看之下,使用 STL 的 std::transform 和 std::tolower 没什么问题,事实上却踩了三个坑:
1、std::tolower 不能直接使用
由于 std::tolower 并不是一个可寻址的函数,因此不能直接作为函数指针传递给 std::transform,需要改为:

het4suzo0b464090170816.png

het4suzo0b464090170816.png

2、字符类型匹配问题
众所周知,std::tolower 只适用于 unsigned char 范围内的字符,如果字符串中有非 ASCII 字符,比如中文、日文、韩文或特殊符号,以及宽字符字符串 std::wstring,std::tolower 都无法正确处理,甚至可能导致未定义行为。
因此,需要用到 std::towlower 但这仍然有问题,因为它无法正确处理 UTF-16 编码中的代理对(surrogate pairs),也就是那些需要两个 wchar_t 来表示的字符。

gd3ubo3xzty64090170916.png

gd3ubo3xzty64090170916.png

3、字符长度变化
有些字符在转换大小写后,长度会发生变化。举个例子:
? 德语的特殊字符 “?” (U+00DF),转换成大写后变成了 “SS”,长度从 1 变成了 2。
? 合字字符,如拉丁小写连字 “?” (U+FB02),转换成大写后变成两个字符 “FL”。
? 在某些语言中,字符转换大小写后可能会消失或新增。
逐字符转换无法处理上述这些情况,会导致字符串截断或数据损坏。
那么,正确的姿势是什么?
要正确地进行字符串大小写转换,应该使用能够全面处理 Unicode 的函数:
1、 Windows 平台:使用 LCMapStringEx 函数:

4huq21nxs3g64090171017.png

4huq21nxs3g64090171017.png

2.、跨平台解决方案:使用 ICU(International Components for Unicode)库:

xek33w3glbo64090171117.png

xek33w3glbo64090171117.png

感兴趣的小伙伴可以阅读原帖:https://devblogs.microsoft.com/oldnewthing/20241007-00/?p=110345——EOF——你好,我是飞宇。日常分享C/C++、计算机学习经验、工作体会,欢迎点击此处查看我以前的学习笔记&经验&分享的资源。
我组建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起进群交流。

i33iwi4xin064090171217.png

i33iwi4xin064090171217.png

欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些计算机学习经验以及工作体验,还有一些内推机会。

gtehuvr1psk64090171317.png

gtehuvr1psk64090171317.png

加个微信,打开另一扇窗
经常遇到有读者后台私信想要一些编程学习资源,这里分享 1T 的编程电子书、C/C++开发手册、Github上182K+的架构路线图、LeetCode算法刷题笔记等精品学习资料,点击下方公众号会回复"编程"即可免费领取~
感谢你的分享,点赞,在看三  

qnan41gjjop64090171417.gif

qnan41gjjop64090171417.gif

回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表