我試圖理解他們倆但strcoll()
this參考說它strcmp()和strcoll()之間有什麼區別?
比較根據當前區域設置兩個空終止字符串由LC_COLLATE類別定義我沒有找到除任何差異。
關於第二個想法,我知道我問另一個問題的詳細答案,這個區域設置是什麼,對於C和C++?
我試圖理解他們倆但strcoll()
this參考說它strcmp()和strcoll()之間有什麼區別?
比較根據當前區域設置兩個空終止字符串由LC_COLLATE類別定義我沒有找到除任何差異。
關於第二個想法,我知道我問另一個問題的詳細答案,這個區域設置是什麼,對於C和C++?
strcmp()
由一個取一個字符串的字節並且是無論字節是對它們進行比較。
strcoll()
需要的字節數,使用語言環境轉換它們,然後將結果進行比較。轉換根據語言重新排序。在法語中,突出的字母出現在非加重字母之後。所以之後是e。但是,之前是f。 strcoll()
正確。 strcmp()
不太好。
然而,在許多情況下strcmp()
是不夠,因爲你並不需要顯示在使用的語言(區域)排序結果。例如,如果您只需要快速訪問由字符串索引的大量數據,則可以使用由該字符串索引的映射。這可能是完全無用的排序使用strcoll()
一般是非常慢(相比於strcmp()
至少)
有關,你可能還需要檢查出Unicode網站字符的詳細信息的。
關於語言環境,這是語言。默認情況下它被設置爲「C」(或多或少,沒有語言環境)。一旦你選擇一個位置,相應地設置區域設置。您也可以設置LC_LOCALE環境變量。實際上有很多這樣的變量。但通常情況下,您會使用預定義的函數自動將這些變量考慮在內,併爲您做正確的事情。 (即格式化日期/時間,格式編號/度量,計算大小寫等)
+1此答案中的字符比較樣本非常好地呈現,尤其是「然而,é在f之前。」例。同樣,有關使用'strcmp()'進行內部排序管理和顯示的說明同樣做得很好。有一些簡潔而且容量很大的答案,我希望我可以不止一次地對它們進行投票。這是其中之一。 – WhozCraig
由於某些原因,在我測試的所有unicode語言環境中,幾個不同版本的glibc中,strcoll()平假名。這打破了排序,uniq,以及以某種方式與字符串順序交互的一切。
$ echo -e -n'い\ nろ\ nは\ nに\ nほ\ nへ\ nと\ n'排序| uniq的
い
這簡直是壞無法修復。來自世界不同地方的人可能對'い'應該放在'ろ'之前還是之後有不同的想法,但是沒有人會認爲它們是相同的。
不,你的區域設置了日本一個無關緊要:
$ LC_ALL = ja_JP.utf8 LANG = ja_JP.utf8 LC_COLLATE = Ja_JP表示。utf8 echo -e -n'い\ nろ\ nは\ nに\ nほ\ nへ\ nと\ n'|排序| uniq的
い
有一些官方的郵件列表討論,但你猜怎麼着,那是在2002年,它被永遠定格,因爲人們不關心:https://www.mail-archive.com/[email protected]/msg02658.html
這個bug發生我們在一天之內,最後我們唯一的出路是將collate locale設置爲「C」,並依靠utf-8編碼的優良屬性。這是一個非常糟糕的經歷,因爲在處理全日文數據時,不應該在「C」語言環境下真正工作。
因此,爲了您的理智,不要直接使用strcoll。一個更安全的變體可能是:
int safe_strcoll(const char *a, const char *b)
{
int ret = strcoll(a, b);
if (ret != 0) return ret;
return strcmp(a, b);
}
以防萬一的strcoll()決定擰你...
我很幸運發現問題。你的環境改變只適用於'echo'。你應該把語言的變化應用到'sort'和'uniq';最簡單的就是'輸出LANG'。它可以很好地工作:'(export LANG = ja_JP.UTF-8; echo -e -n'い\ nろ\ nは\ nに\ nほ\ nへ\ nと\ n'| sort | uniq)' 。 – qsantos
謝謝你指出。除了第一次做這個實驗時,我實際上正在使用export LANG = ja_JP.UTF-8。我在多臺機器上再次嘗試,並且仍然可以在一些但不是全部的問題中重現問題。 我想我需要進一步挖掘導致差異的原因。 glibc版本似乎不是我需要控制的唯一變量... –
的[例如這裏(http://en.cppreference.com/w/cpp/string/byte/strcoll)在我看來很清楚。 – Rapptz
@Rapptz ...哎呀...應該看到鏈接....在發佈之前... – Recker
hrnec before chrt :) +1 – davak