gpt4 book ai didi

c++ - 模板化的字符串类使用strcmp,strcpy和strlen

转载 作者:太空狗 更新时间:2023-10-29 20:00:07 29 4
gpt4 key购买 nike

我前段时间听说过有关如何创建模板化字符串类的讨论,您不应该为可以利用UTF8和UTF16的模板化字符串类使用strcmp,strcpy和strlen。据我所知,您应该使用algorithm.h中的函数,但是,我不记得实现的方式或原因。有人可以解释使用什么功能代替,如何使用它们以及为什么吗?

模板化字符串类的示例如下所示:

String<UTF8> utf8String;
String<UTF16> utf16String;

这是UTF8是无符号字符和UTF16是无符号short的地方。

最佳答案

首先,C++不需要其他字符串类。可能已经开发了成百上千的字符串类,而您的类不会改善这种情况。除非您纯粹出于教育目的而这样做,否则您应该三思而后行,然后决定不编写新的。

您可以使用std::basic_string<char>来保存UTF-8代码单元序列,std::basic_string<char16_t>来保存UTF-16代码单元序列,std::basic_string<char32_t>来保存UTF-32代码单元序列,等等。C++甚至为这些类型提供了简短的方便名称:stringu16string,和u32stringbasic_string通过提供成员函数来复制,比较并获取可用于其模板化的任何代码单元的字符串的长度,已经解决了您在此处提出的问题。

我想不出没有与遗留代码接口(interface)的新代码的任何正当理由,以不使用其他任何东西作为字符串的规范存储类型。即使您确实与使用其他代码的遗留代码进行了接口(interface),即使该接口(interface)的表面积不大,您也可能仍应使用一种标准类型,而不要使用其他任何类型,当然,如果您要与遗留代码进行接口(interface)您仍将使用该旧类型,而不是编写自己的新类型。

话虽如此,您不能对模板化的字符串类型使用strcmpstrcpystrlen的原因是它们都对以空终止的字节序列进行操作。如果您的代码单元大于一个字节,那么在实际终止空代码单元之前可能有零个字节(假设您根本不使用空终止,那么您可能不应该这样做)。考虑字符串“Hello”的UTF-16表示形式的字节(在一点字节序的机器上)。

48 00 65 00 6c 00 6c 00  6f 00

由于UTF-16使用16位代码单元,因此字符'H'最终存储为两个字节 48 00。通过假定第一个空字节为结尾来对上述字节序列进行操作的函数将假定第一个字符的后一半标记整个字符串的结尾。这显然是行不通的。

因此, strcmpstrcpystrlen都是算法的专用版本,可以更广泛地实现。由于它们仅适用于字节序列,并且您需要使用代码单元序列可能大于字节的代码单元序列,因此需要可与​​任何代码单元一起使用的通用算法。提供的标准库提供了许多通用算法。这是我对替换这些 str*函数的建议。
strcmp比较两个代码单元序列,如果两个序列相等,则返回0;如果第一个序列在字典上小于第二个序列,则返回正数;否则返回负数。标准库包含通用算法 lexicographical_compare,它执行几乎相同的操作,不同之处在于,如果第一个序列在字典上小于第二个序列,则返回true,否则返回false。
strcpy复制代码单元序列。您可以改用标准库的 copy算法。
strlen使用一个指向代码单位的指针,并在找到空值之前对代码单位的数量进行计数。如果您需要此函数,而不是仅告诉您字符串中代码单元数的函数,则可以通过传递空值作为要查找的值,使用 find算法实现该函数。相反,如果您想查找序列的实际长度,则您的类应该只提供 size方法,该方法可以直接访问您的类内部使用的用于存储大小的任何方法。

str*函数不同,我建议的算法需要两个迭代器来划分代码单元序列。一个指向序列中第一个元素,另一个指向序列中最后一个元素之后的位置。 str*函数仅使用指向第一个元素的指针,然后假定序列继续进行,直到找到第一个零值代码单元为止。当您实现自己的模板化字符串类时,最好也摆脱显式的空终止约定,而只提供一种 end()方法,该方法可为您的字符串提供正确的端点。

关于c++ - 模板化的字符串类使用strcmp,strcpy和strlen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8686651/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com