std :: stringの文字数を取得する方法は?


回答:


177

を使用している場合はstd::string、次を呼び出しますlength()

std::string str = "hello";
std::cout << str << ":" << str.length();
// Outputs "hello:5"

c-stringを使用している場合は、を呼び出しますstrlen()

const char *str = "hello";
std::cout << str << ":" << strlen(str);
// Outputs "hello:5"

または、Pascalスタイルの文字列(または、ジョエルスポルスキー後続のNULLを持っているときにそれらを呼び出すのが好きな f *****文字列)を使いたければ、最初の文字を逆参照するだけです。

const char *str = "\005hello";
std::cout << str + 1 << ":" << *str;
// Outputs "hello:5"

7
パスカルスタイルの文字列を使用するのは誰でしょうか。
Xarn、2014

17
length()は文字数ではなくバイト数を返しませんか?

2
std :: stringの場合も同じです(可変長エンコーディングを格納する場合、またはstd :: stringを使用してマルチバイト文字を格納する場合を除く)。これを行っている場合、stdライブラリからのサポートはあまり得られないため、独自のstrlenのローリングも処理できます。wstring、u16string、u32stringの場合は、バイトではなく文字数を返します。(ただし、これらのいずれかで可変長エンコーディングを使用している場合は、独自のstrlenをロールバックする必要があります)。
Eclipseの

4
これは、この高い評価の回答に値を追加して、戻り値のタイプについて言及しますstd::size_t
chux-モニカを2015年

3
以下のための+1 @Eclipse F *** ED文字列
Sнаđошƒаӽ

23

C ++文字列(std :: string)を扱うときは、length()またはsize()を探します。どちらも同じ値を提供するはずです。ただし、Cスタイルの文字列を扱う場合は、strlen()を使用します。

#include <iostream>
#include <string.h>

int main(int argc, char **argv)
{
   std::string str = "Hello!";
   const char *otherstr = "Hello!"; // C-Style string
   std::cout << str.size() << std::endl;
   std::cout << str.length() << std::endl;
   std::cout << strlen(otherstr) << std::endl; // C way for string length
   std::cout << strlen(str.c_str()) << std::endl; // convert C++ string to C-string then call strlen
   return 0;
}

出力:

6
6
6
6

5
非推奨の#include <string.h>の代わりに#include <cstring>を使用すると、コンパイラの警告(特定のC ++コンパイラ)を回避できることに注意してください
Colin

1
例ではASCIIを使用しています。Unicode文字についても更新しますか?特にasなどの32ビットのもの
Thomas Weller

17

それはあなたが話している文字列のタイプに依存します。文字列には多くの種類があります。

  1. const char* -Cスタイルのマルチバイト文字列
  2. const wchar_t* -Cスタイルのワイド文字列
  3. std::string -「標準」マルチバイト文字列
  4. std::wstring -「標準」のワイド文字列

3と4では、.size()または.length()メソッドを使用できます。

1の場合、使用できます strlen()が、文字列変数がNULL(=== 0)でないことを確認する必要があります

2の場合はを使用できますwcslen()が、文字列変数がNULL(=== 0)でないことを確認する必要があります

MFC CString、ATL CComBSTR、ACE などの非標準のC ++ライブラリには、などのACE_CStringメソッドを持つ他の文字列型があります.GetLength()。私はそれらの詳細を頭のてっぺんから思い出せません。

STLSoftのライブラリは、彼らが呼んでいるもので、このすべての抽象化している文字列のアクセスシム任意の型から文字列の長さ(および他の態様)を取得するために使用することができ、。したがって、上記のすべて(非標準ライブラリを含む)で同じ関数を使用しますstlsoft::c_str_len()この記事では、すべてが完全に明白または簡単なわけではないため、すべてがどのように機能するかについて説明します。


1
oneなどの32ビット文字に適しているのはどれですか。
トーマスウェラー

4

Unicodeの場合

ここでいくつかの答えはそれを扱っています .length()は、マルチバイト文字で誤った結果をもたらすが、11の回答があり、どれも解決策を提供していません。

Z͉̳̺ͥͬ̾a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚の場合

まず第一に、あなたが「長さ」によってあなたが何を意味するかを知ることは重要です。動機付けの例として、「Z "a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚」という文字列を検討してください(一部の言語、特にタイ語では、実際に分音記号を組み合わせて使用​​しているため、これは15歳のミームに役立つだけでなく、最も重要な使用例です) 。UTF-8でエンコードされていると仮定します。この文字列の長さについては、次の3つの方法で説明できます。

95バイト

00000000: 5acd a5cd accc becd 89cc b3cc ba61 cc92  Z............a..
00000010: cc92 cd8c cc8b cdaa ccb4 cd95 ccb2 6ccd  ..............l.
00000020: a4cc 80cc 9acc 88cd 9ccc a8cd 8ecc b0cc  ................
00000030: 98cd 89cc 9f67 cc92 cd9d cd85 cd95 cd94  .....g..........
00000040: cca4 cd96 cc9f 6fcc 90cd afcc 9acc 85cd  ......o.........
00000050: aacc 86cd a3cc a1cc b5cc a1cc bccd 9a    ...............

50コードポイント

LATIN CAPITAL LETTER Z
COMBINING LEFT ANGLE BELOW
COMBINING DOUBLE LOW LINE
COMBINING INVERTED BRIDGE BELOW
COMBINING LATIN SMALL LETTER I
COMBINING LATIN SMALL LETTER R
COMBINING VERTICAL TILDE
LATIN SMALL LETTER A
COMBINING TILDE OVERLAY
COMBINING RIGHT ARROWHEAD BELOW
COMBINING LOW LINE
COMBINING TURNED COMMA ABOVE
COMBINING TURNED COMMA ABOVE
COMBINING ALMOST EQUAL TO ABOVE
COMBINING DOUBLE ACUTE ACCENT
COMBINING LATIN SMALL LETTER H
LATIN SMALL LETTER L
COMBINING OGONEK
COMBINING UPWARDS ARROW BELOW
COMBINING TILDE BELOW
COMBINING LEFT TACK BELOW
COMBINING LEFT ANGLE BELOW
COMBINING PLUS SIGN BELOW
COMBINING LATIN SMALL LETTER E
COMBINING GRAVE ACCENT
COMBINING DIAERESIS
COMBINING LEFT ANGLE ABOVE
COMBINING DOUBLE BREVE BELOW
LATIN SMALL LETTER G
COMBINING RIGHT ARROWHEAD BELOW
COMBINING LEFT ARROWHEAD BELOW
COMBINING DIAERESIS BELOW
COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW
COMBINING PLUS SIGN BELOW
COMBINING TURNED COMMA ABOVE
COMBINING DOUBLE BREVE
COMBINING GREEK YPOGEGRAMMENI
LATIN SMALL LETTER O
COMBINING SHORT STROKE OVERLAY
COMBINING PALATALIZED HOOK BELOW
COMBINING PALATALIZED HOOK BELOW
COMBINING SEAGULL BELOW
COMBINING DOUBLE RING BELOW
COMBINING CANDRABINDU
COMBINING LATIN SMALL LETTER X
COMBINING OVERLINE
COMBINING LATIN SMALL LETTER H
COMBINING BREVE
COMBINING LATIN SMALL LETTER A
COMBINING LEFT ANGLE ABOVE

5書記

Z with some s**t
a with some s**t
l with some s**t
g with some s**t
o with some s**t

ICUを使用して長さを見つける

ICUにはC ++クラスがありますが、UTF-16に変換する必要があります。Cのタイプとマクロを直接使用して、いくつかのUTF-8サポートを取得できます。

#include <memory>
#include <iostream>
#include <unicode/utypes.h>
#include <unicode/ubrk.h>
#include <unicode/utext.h>

//
// C++ helpers so we can use RAII
//
// Note that ICU internally provides some C++ wrappers (such as BreakIterator), however these only seem to work
// for UTF-16 strings, and require transforming UTF-8 to UTF-16 before use.
// If you already have UTF-16 strings or can take the performance hit, you should probably use those instead of
// the C functions. See: http://icu-project.org/apiref/icu4c/
//
struct UTextDeleter { void operator()(UText* ptr) { utext_close(ptr); } };
struct UBreakIteratorDeleter { void operator()(UBreakIterator* ptr) { ubrk_close(ptr); } };
using PUText = std::unique_ptr<UText, UTextDeleter>;
using PUBreakIterator = std::unique_ptr<UBreakIterator, UBreakIteratorDeleter>;

void checkStatus(const UErrorCode status)
{
    if(U_FAILURE(status))
    {
        throw std::runtime_error(u_errorName(status));
    }
}

size_t countGraphemes(UText* text)
{
    // source for most of this: http://userguide.icu-project.org/strings/utext
    UErrorCode status = U_ZERO_ERROR;
    PUBreakIterator it(ubrk_open(UBRK_CHARACTER, "en_us", nullptr, 0, &status));
    checkStatus(status);
    ubrk_setUText(it.get(), text, &status);
    checkStatus(status);
    size_t charCount = 0;
    while(ubrk_next(it.get()) != UBRK_DONE)
    {
        ++charCount;
    }
    return charCount;
}

size_t countCodepoints(UText* text)
{
    size_t codepointCount = 0;
    while(UTEXT_NEXT32(text) != U_SENTINEL)
    {
        ++codepointCount;
    }
    // reset the index so we can use the structure again
    UTEXT_SETNATIVEINDEX(text, 0);
    return codepointCount;
}

void printStringInfo(const std::string& utf8)
{
    UErrorCode status = U_ZERO_ERROR;
    PUText text(utext_openUTF8(nullptr, utf8.data(), utf8.length(), &status));
    checkStatus(status);

    std::cout << "UTF-8 string (might look wrong if your console locale is different): " << utf8 << std::endl;
    std::cout << "Length (UTF-8 bytes): " << utf8.length() << std::endl;
    std::cout << "Length (UTF-8 codepoints): " << countCodepoints(text.get()) << std::endl;
    std::cout << "Length (graphemes): " << countGraphemes(text.get()) << std::endl;
    std::cout << std::endl;
}

void main(int argc, char** argv)
{
    printStringInfo(u8"Hello, world!");
    printStringInfo(u8"หวัดดีชาวโลก");
    printStringInfo(u8"\xF0\x9F\x90\xBF");
    printStringInfo(u8"Z͉̳̺ͥͬ̾a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚");
}

これは印刷します:

UTF-8 string (might look wrong if your console locale is different): Hello, world!
Length (UTF-8 bytes): 13
Length (UTF-8 codepoints): 13
Length (graphemes): 13

UTF-8 string (might look wrong if your console locale is different): หวัดดีชาวโลก
Length (UTF-8 bytes): 36
Length (UTF-8 codepoints): 12
Length (graphemes): 10

UTF-8 string (might look wrong if your console locale is different): 🐿
Length (UTF-8 bytes): 4
Length (UTF-8 codepoints): 1
Length (graphemes): 1

UTF-8 string (might look wrong if your console locale is different): Z͉̳̺ͥͬ̾a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚
Length (UTF-8 bytes): 95
Length (UTF-8 codepoints): 50
Length (graphemes): 5

Boost.Localeは ICUをラップし、より優れたインターフェースを提供する可能性があります。ただし、それでもUTF-16との変換が必要です。


3

新しいSTLスタイルの文字列ではなく、古いCスタイルの文字列を使用している場合strlen、Cランタイムライブラリに関数があります。

const char* p = "Hello";
size_t n = strlen(p);

3

std :: stringを使用している場合、2つの一般的な方法があります。

std::string Str("Some String");
size_t Size = 0;
Size = Str.size();
Size = Str.length();

Cスタイルの文字列を使用している場合(char *またはconst char *を使用)、次のように使用できます。

const char *pStr = "Some String";
size_t Size = strlen(pStr);

2
string foo;
... foo.length() ...

.lengthと.sizeは同義語ですが、 "length"は少し明確な言葉だと思います。


一部の実装では「length()+ 1」を返すと聞いたので、size()は推奨されません(nullターミネーターが含まれているため)。したがって、よりクリーンで移植性の高いlength()を使用してください。

1
@LaQuet、標準に準拠したコンパイラまたはSTL実装を使用していない場合は、さらに多くのことを心配する必要があります。
ストレッジャー、2009年

2
標準のC ++文字列のように当てはまるはずのない@Nelsonはnullで終了しません。ただし、c_str()を使用してキャストすると、最後にnullバイトが追加されます。
ジョンT



2

C ++ std :: stringでは、length()およびsize()メソッドはバイト数を提供しますが、必ずしも文字数を提供するわけではありません! c-Style sizeof()関数と同じです!

印刷可能なほとんどの7ビットASCII文字の場合、これは同じ値ですが、7ビットASCII以外の文字の場合、これは間違いなく異なります。実際の結果を得るには、次の例を参照してください(64ビットLinux)。

文字数を実際にカウントできる単純なc / c ++関数はありません。ちなみに、これらのものはすべて実装に依存しており、他の環境(コンパイラ、Win 16/32、Linux、組み込みなど)では異なる場合があります。

次の例を参照してください。

#include <string>
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int main()
{
/* c-Style char Array */
const char * Test1 = "1234";
const char * Test2 = "ÄÖÜ€";
const char * Test3 = "αβγ𝄞";

/* c++ string object */
string sTest1 = "1234";
string sTest2 = "ÄÖÜ€";
string sTest3 = "αβγ𝄞";

printf("\r\nC Style Resluts:\r\n");
printf("Test1: %s, strlen(): %d\r\n",Test1, (int) strlen(Test1));
printf("Test2: %s, strlen(): %d\r\n",Test2, (int) strlen(Test2));
printf("Test3: %s, strlen(): %d\r\n",Test3, (int) strlen(Test3));

printf("\r\nC++ Style Resluts:\r\n");
cout << "Test1: " << sTest1 << ", Test1.size():  " <<sTest1.size() <<"  sTest1.length(): " << sTest1.length() << endl;
cout << "Test1: " << sTest2 << ", Test2.size():  " <<sTest2.size() <<"  sTest1.length(): " << sTest2.length() << endl;
cout << "Test1: " << sTest3 << ", Test3.size(): " <<sTest3.size() << "  sTest1.length(): " << sTest3.length() << endl;
return 0;
}

この例の出力は次のとおりです。

C Style Results:
Test1: ABCD, strlen(): 4    
Test2: ÄÖÜ€, strlen(): 9
Test3: αβγ𝄞, strlen(): 10

C++ Style Results:
Test1: ABCD, sTest1.size():  4  sTest1.length(): 4
Test2: ÄÖÜ€, sTest2.size():  9  sTest2.length(): 9
Test3: αβγ𝄞, sTest3.size(): 10  sTest3.length(): 10

0

文字列を入力してその長さを見つける最も簡単な方法かもしれません。

// Finding length of a string in C++ 
#include<iostream>
#include<string>
using namespace std;

int count(string);

int main()
{
string str;
cout << "Enter a string: ";
getline(cin,str);
cout << "\nString: " << str << endl;
cout << count(str) << endl;

return 0;

}

int count(string s){
if(s == "")
  return 0;
if(s.length() == 1)
  return 1;
else
    return (s.length());

}

4
count(string)がそのstring :: length()がしないと思うのは何ですか?文字列の余分なコピーを不必要に作成し、文字列に20億以上の文字がある場合は負の値を返します。
Eclipseの

0

std名前空間を気にせずに文字列の長さを取得する最も簡単な方法は次のとおりです

スペースあり/なしの文字列

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    getline(cin,str);
    cout<<"Length of given string is"<<str.length();
    return 0;
}

スペースのない文字列

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    cin>>str;
    cout<<"Length of given string is"<<str.length();
    return 0;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.