私のstd :: stringsはUTF-8でエンコードされるので、std :: string <演算子はそれをカットしません。 2つのutf-8でエンコードされたstd :: stringsをどのように比較できますか?UTF-8文字列をソートする?
それがアクセントのためにあるカットしない場合、Eは、それはすべきではない
zの後に来るのおかげ
私のstd :: stringsはUTF-8でエンコードされるので、std :: string <演算子はそれをカットしません。 2つのutf-8でエンコードされたstd :: stringsをどのように比較できますか?UTF-8文字列をソートする?
それがアクセントのためにあるカットしない場合、Eは、それはすべきではない
zの後に来るのおかげ
あなたは、エンコードされたUTF-8にソートされているもの辞書式順序を(したくない場合UTF-8でエンコードされた文字列を適切にUCS-2またはUCS-4にデコードし、適切な比較関数を適用する必要があります。
UTF-8エンコーディングの仕組みは巧みに設計されており、8ビットのエンコードされた各バイトの数値を並べ替えた場合、と同じが最初にデコードされたようになります文字列をUnicodeに変換し、各コードポイントの数値を比較します。
更新:更新された質問は、純粋に辞書編集の並べ替えよりも複雑な比較機能が必要であることを示しています。 UTF-8文字列をデコードし、デコードされた文字を比較する必要があります。
UTF-16エンコーディングはその機能を持っていないことに注意してください。 – dan04
@ dan04:どのような機能がありませんか? –
バイト配列ANSIスタイルとして扱わない限り、照合(ソート)とエンコーディングは全く別の2つの問題です。 http://www.joelonsoftware.com/articles/Unicode.html –
エンコーディング(UTF-8,16など)は問題ではありません。コンテナ自体が文字列をUnicode文字列または8ビット(ASCIIまたはLatin-1)文字列として扱っているかどうかは重要です。
Is there an STL and UTF-8 friendly C++ Wrapper for ICU, or other powerful Unicode libraryが見つかりました。
標準で照合(ソート)などのロケール固有のものについてはstd::locale
です。環境にLC_COLLATE=en_US.utf8
などが含まれている場合、このプログラムは必要に応じて行をソートします。
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <locale>
#include <string>
#include <vector>
class collate_in : public std::binary_function<std::string, std::string, bool> {
protected:
const std::collate<char> &coll;
public:
collate_in(std::locale loc)
: coll(std::use_facet<std::collate<char> >(loc)) {}
bool operator()(const std::string &a, const std::string &b) const {
// std::collate::compare() takes C-style string (begin, end)s and
// returns values like strcmp or strcoll. Compare to 0 for results
// expected for a less<>-style comparator.
return coll.compare(a.c_str(), a.c_str() + a.size(),
b.c_str(), b.c_str() + b.size()) < 0;
}
};
int main() {
std::vector<std::string> v;
copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(), back_inserter(v));
// std::locale("") is the locale from the environment. One could also
// std::locale::global(std::locale("")) to set up this program's global
// first, and then use locale() to get the global locale, or choose a
// specific locale instead of using the environment's.
sort(v.begin(), v.end(), collate_in(std::locale("")));
copy(v.begin(), v.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
$ cat >file f é e d ^D $ LC_COLLATE=C ./a.out file d e f é $ LC_COLLATE=en_US.utf8 ./a.out file d e é f
私は上記に書いたstd::collate<>::compare(a, b) < 0
ラッパーをなくし、std::locale::operator()(a, b)
が存在していることを私の注意に持って来られています。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <locale>
#include <string>
#include <vector>
int main() {
std::vector<std::string> v;
copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(), back_inserter(v));
sort(v.begin(), v.end(), std::locale(""));
copy(v.begin(), v.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
1つのオプションは、ICUの丁合あなたはその後、並べ替えに使用することができ、適切に国際化された「比較する」方法を提供する(http://userguide.icu-project.org/collation/api)を用いることであろう。
クロムはなぜ標準 `opが<`「それをカットしない」はありません再利用
/&ペーストをコピーする簡単なはずの小さなラッパを持っていますか?何を注文しますか? –
UTF-8でエンコードされた文字列は、同等のUTF-32でエンコードされた文字列と同じ順序でソートされます。 – dan04
@Charles:私はそれが単にバイト単位の比較を実行し、アクセントなどを考慮しないので、「カット」しないと信じています。 – Mehrdad