![](/img/trans.png)
[英]Replace all non-ASCII characters in a string by their ASCII equivalent
[英]Reverse string with non-ASCII characters
我想用特殊字符更改字符串中的顺序,如下所示:
ZAŻÓŁĆGĘŚLĄJAŹŃ
至
ŃŹAJĄŁŚĘGĆŁÓŻAZ
我尝试使用std :: reverse
std::string text("ZAŻÓŁĆ GĘŚLĄ JAŹŃ!");
std::cout << text << std::endl;
std::reverse(text.rbegin(), text.rend());
std::cout << text << std::endl;
但输出显示:
ZAŻÓŁĆGĘŚLĄJAŹŃ!
!\\203Ź\\ 305AJ \\ 204 \\ 304L \\232Ř\\ 304G \\206āœû\\ 305AZ < - 反向弦
所以我尝试“手动”:
std::string text1("ZAŻÓŁĆ GĘŚLĄ JAŹŃ!");
std::cout << text1 << std::endl;
int count = (int) floorf(text1.size() /2.f);
std::cout << count << " " << text1.size() << std::endl;
unsigned int maxIndex = text1.size() - 1;
for (int i = 0; i < count ; i++)
{
char tmp = text1[i];
text1[i] = text1[maxIndex];
text1[maxIndex] = tmp;
maxIndex--;
}
std::cout << text1 << std::endl;
但在这种情况下,我在text1.size()中遇到问题,因为每个特殊字符都被计算两次:
ZAŻÓŁĆGĘŚLĄJAŹŃ!
13 27 < - 第二个数字是text1.size()
!\\203Ź\\ 305AJ \\ 204 \\ 304L \\232Ř\\ 304G \\206āœû\\ 305AZ
如何用特殊字符反转字符串的正确方法?
您的代码确实正确地反转了字符串中的字节,这里没有任何错误。 但问题是你的编译器存储了你的文字字符串“ZAŻÓŁĆGĘŚLĄJAŹŃ!” 采用UTF-8编码。
并且UTF-8将除了匹配ASCII的字符之外的所有字符存储为可变长度的字节序列 。 这意味着一个char
(一个字节)不再是一个字符,因此反转char
现在与反转字符不同。
为了实现您的目标,您至少有两个选择:
UPD:一个很好的链接: http : //www.joelonsoftware.com/articles/Unicode.html
您可以自己编写reverseUt8函数代码:
std::string getMultiByteReversed(char ch1, char ch2)
{
if (ch == '\xc3') // most utf8 characters
return std::string(ch1)+ std::string(ch2);
} else {
return std::string(ch1);
}
}
std::string reverseMultiByteString(const std::string &s)
{
std::string result;
for (std::string::reverse_iterator it = s.rbegin(); it != s.rend(); ++it) {
std::string reversed;
if ( (it+1) != rbegin() && (reversed = getMultiByteReversed(*it, *it+1) ) {
result += reversed;
++it;
} else {
result += *it;
}
}
return result;
}
您可以在http://www.utf8-chartable.de/查找utf8代码
这里有几个问题。 答案很复杂,可能完全取决于您要做的事情。
首先是(如其他答案所述)如果您的字符串是UTF-8编码,则一个Unicode代码点可能包含多个字节。 如果你只是反转字节,你将打破UTF-8编码。 对此最简单(但不一定是最好的)修复是将字符串转换为UTF-32并反转32位代码点而不是字节。
下一个问题是单个字素可能包含多个Unicode代码点。 例如,“é”可以编码为两个代码点U + 0065,后跟U + 0301。 如果颠倒这些顺序,那将打破它,因为组合字符U + 301现在将与不同的基本字符相关联。 所以“神奇宝贝”逆转这种方式会变成“noḿekoP”,重音超过“m”而不是“e”。
现在你可能会认为你可以通过首先将字符串规范化为组合形式来解决这个问题。 然而,这有其自身的问题,因为并非每个字形都可以由单个代码点表示。 例如,加拿大标志表情符号(🇨🇦)由代码点U + 1F1E8表示,后跟代码点U + 1F1E6。 它没有单一的代码点。 如果您反转其代码点,则会获得Ascension Island(🇦🇨)的标记。
然后你就有了基于上下文改变形式的语言,而且我对处理这些语言还不太了解。
它可能更接近您想要反转字形集群 。 请参阅UAX29:Unicode文本分段 。
你尝试过逐个交换字符吗? 例如,如果字符串长度为奇数,则将第一个字符与最后一个字符交换,将第二个字符与第二个字符交换,直到中间字符为左。 如果字符串lengt是偶数,则将1st替换为last,将2nd替换为second last,直到两个中间字符都被交换。 这样,字符串就会反转。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.