![](/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.