2017-10-26 23 views
6

次のプログラムでは、非ASCII文字を含む文字列の長さを測定しようとしています。ASCII以外の文字の正しいサイズを測定するにはどうすればよいですか?

しかし、非ASCII文字を使用しているときにsize()が正しい長さを印刷しない理由がわかりません。

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string s1 = "Hello"; 
    std::string s2 = "इंडिया"; // non-ASCII string 
    std::cout << "Size of " << s1 << " is " << s1.size() << std::endl; 
    std::cout << "Size of " << s2 << " is " << s2.size() << std::endl; 
} 

出力:

Size of Hello is 5 
Size of इंडिया is 18 

ライブデモWandbox

+0

ため

重要性の参照リンクhereを意味は何? –

+0

文字列の正しい出力は6です。 – rsp

+0

@rsp、 'std :: wstring'でサイズ' 6'を取得します – DAle

答えて

1

私はstd::wstring_convertクラスを使用して文字列の正しい長さを持っています。

#include <string> 
#include <iostream> 
#include <codecvt> 

int main() 
{ 
    std::string s1 = "Hello"; 
    std::string s2 = "इंडिया"; // non-ASCII string 
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> cn; 
    auto sz = cn.from_bytes(s2).size(); 
    std::cout << "Size of " << s2 << " is " << sz << std::endl; 
} 

ライブデモwandbox。あなたは「正しい出力」することで、よりおよそstd::wstring_convert

4

std::string::sizeは、長さを文字数ではなくバイト数で返します。 2番目の文字列はUNICODEエンコーディングを使用しているため、文字あたり数バイトかかることがあります。 std::wstring::sizeは、エンコーディングによって異なります(実際の文字ではなく、ワイド文字の数が返されるため、UTF-16を使用すると他のエンコーディングと一致しますが、必ずしも一致しません)。in this answer

実際の長さ(記号の数)を測定するには、文字を正しく(したがってカウントする)ためにエンコーディングを知る必要があります。 This answerは、UTF-8などの場合に役立ちます(ただし、使用されるメソッドはC++では廃止予定17)。

UTF-8のための別のオプションは、最初のバイト(credit to this other answer)の数を数えることである。

int utf8_length(const std::string& s) { 
    int len = 0; 
    for (auto c : s) 
     len += (c & 0xc0) != 0x80; 
    return len; 
} 
+2

code_pointの数は抽象的な文字の数と異なる場合があることに注意してください。 – Jarod42

+1

リテラル文字列として、2番目の文字列は、コンパイラがemit([-fexec-charset](https://gcc.gnu.org/onlinedocs/cpp/Invocation.html)または同等のもの)に指示された実行文字エンコーディングを使用します。 、はい、UTF-8のデフォルトの可能性があります。 –

関連する問題