我想用特殊字符更改字符串中的顺序:
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&lt; - 反向字符串
所以我尝试“手动”:
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&lt; - 秒数是text1.size()
!\203Ź\ 305AJ \ 204 \ 304L \232Ř\ 304G \206āœû\ 305AZ
如何用特殊字符反转字符串的正确方法?
答案 0 :(得分:0)
您的代码确实正确地反转了字符串中的字节,这里没有任何错误。但问题是你的编译器存储了你的文字字符串“ZAŻÓŁĆGĘŚLĄJAŹŃ!”采用UTF-8编码。
UTF-8将除ASCII匹配的所有字符存储为字节的可变长度序列。这意味着一个char
(一个字节)不再是一个字符,因此反转char
现在与反转字符不同。
为了实现目标,您至少有两个选择:
UPD:一个不错的链接:http://www.joelonsoftware.com/articles/Unicode.html
答案 1 :(得分:0)
您可以自己编写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;
}
上查找utf8代码
答案 2 :(得分:0)
这里有几个问题。答案很复杂,并且可能完全取决于您要执行的操作。
首先是(如其他答案所述),如果您的字符串是UTF-8编码的,则一个Unicode代码点可能包含多个字节。如果仅反转字节,则会破坏UTF-8编码。最简单(虽然不一定是最好的)解决方案是将字符串转换为UTF-32并反转32位代码点而不是字节。
下一个问题是,单个字形可能包含多个Unicode代码点。例如,“é”可能被编码为两个代码点U + 0065,后跟U + 0301。如果您颠倒了它们的顺序,则会破坏它,因为组合字符U + 301现在将与另一个基本字符相关联。因此,以这种方式反转的“神奇宝贝”将变成带有“ m”而不是“ e”的重音符号的“noḿekoP”。
现在,您可能会认为可以通过首先将字符串标准化为组合形式来解决此问题。但是,这有其自身的问题,因为并非每个字素都可以由单个代码点表示。例如,加拿大国旗表情符号(??)由代码点U + 1F1E8表示,后跟代码点U + 1F1E6。没有单个代码点。如果反转其代码点,则会获得升腾岛(??)的标志。
然后您有一些语言,这些语言中的字符会根据上下文改变形式,而我对如何处理这些字符还不了解。
它可能更接近于您想要反转字素簇的对象。参见UAX29: Unicode text segmentation。
答案 3 :(得分:-4)