用字符而不是字节进行子str
substr with characters instead of bytes
假设我有一个string s = "101870002PTäPO PVä #Person Tätigkeitsdarstellung 001100001&0111010101101870100092001000010"
当我做一个substring(30,40)
它返回"#Person Tätigkeitsdarstellung",从一个空格开始。我想它是在计算字节而不是字符。
通常字符串的大小是 110,当我做s.length()
或s.size()
时,由于 3 个特殊字符,它返回 113。
我想知道是否有办法避免返回值开头的这个空白区域。
感谢您的帮助!
在 utf-8 中,码位(字符(ä
由两个代码单元(在 utf-8 中为 1 个字节(组成。C++不支持将字符串视为代码点序列。因此,就标准库而言,std::string("ä").size()
为 2。
一个简单的方法是使用 std::wstring
. wstring
使用的字符类型(wchar_t
(至少与系统支持的最宽字符集一样宽。因此,如果系统支持足够宽的编码来表示具有单个代码单元的任何(非复合(unicode 字符,则字符串方法的行为将符合您的预期。目前utf-32已经足够宽了,并且被(大多数?(像操作系统这样的Unix支持。
需要注意的是,Windows 仅支持 utf-16 而不是 utf-32,因此,如果您选择wstring
方法并将程序移植到 Windows,并且程序的用户尝试使用宽度超过 2 个字节的 unicode 字符,则每个代码点一个代码单元的假设不成立。
wstring
方法也不考虑控制或复合字符。
这里有一个小测试代码,它将包含多字节 utf-8 字符ä
的std::string
转换为wstring
:
string foo("ä"); // read however you want
wstring_convert<codecvt_utf8<wchar_t>> converter;
wstring wfoo = converter.from_bytes(foo.data());
cout << foo.size() << endl; // 2 on my system
cout << wfoo.size() << endl; // 1 on my system
不幸的是,libstdc++至少在gcc-4.8中没有实现在c ++ 11中引入的<codecvt>
。如果你不需要libc++,那么类似的功能可能在Boost.Locale中。
或者,如果您希望将代码移植到不支持 utf-32 的系统,则可以继续使用 std::string
并使用外部库进行迭代和计数等。这是一个:http://utfcpp.sourceforge.net/和另一个:http://site.icu-project.org/。我相信这是推荐的方法。
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在UNIX系统中使用DIR查找文件的字节大小
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 当比特(而不是字节)的顺序至关重要时的持久性
- Python str to C++ to Python str
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 字节真的是最小可寻址单元吗
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- Python3 TypeError:一个类似字节的对象是必需的,而不是'str'
- 字节或整数地址预期,而不是str实例python 3
- 用字符而不是字节进行子str