C ++で文字列の文字数を取得するにはどうすればよいですか?
12 に答える
を使用している場合は、次の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"
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
それはあなたが話している文字列の種類に依存します。文字列には多くの種類があります。
const char*
-Cスタイルのマルチバイト文字列const wchar_t*
-Cスタイルのワイドストリングstd::string
-「標準」マルチバイト文字列std::wstring
-「標準」の幅の広い文字列
3および4の場合、.size()
または.length()
メソッドを使用できます。
1の場合、を使用できますがstrlen()
、文字列変数がNULLでないことを確認する必要があります(=== 0)
2の場合、を使用できますがwcslen()
、文字列変数がNULLでないことを確認する必要があります(=== 0)
非標準のC++ライブラリには、MFC CString
、ATL CComBSTR
、ACEなどの他の文字列タイプと、などのACE_CString
メソッドが.GetLength()
あります。それらの詳細を頭のてっぺんから思い出せません。
STLSoftライブラリは、文字列アクセスシムと呼ばれるものでこれをすべて抽象化しました。これは、任意のタイプから文字列の長さ(およびその他の側面)を取得するために使用できます。したがって、同じ関数を使用する上記のすべて(非標準ライブラリのものを含む)に対してstlsoft::c_str_len()
。この記事では、すべてが完全に明白または簡単ではないため、すべてがどのように機能するかについて説明します。
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との間の変換が必要です。
新しいSTLスタイルの文字列の代わりに古いCスタイルの文字列を使用している場合strlen
は、Cランタイムライブラリに次の関数があります。
const char* p = "Hello";
size_t n = strlen(p);
std :: stringを使用している場合、そのための2つの一般的な方法があります。
std::string Str("Some String");
size_t Size = 0;
Size = Str.size();
Size = Str.length();
Cスタイルの文字列(char*またはconstchar *を使用)を使用している場合は、次を使用できます。
const char *pStr = "Some String";
size_t Size = strlen(pStr);
C ++ std :: stringでは、length()およびsize()メソッドはバイト数を提供しますが、必ずしも文字数を提供するわけではありません!。 c-Style sizeof()関数と同じです!
ほとんどの印刷可能な7bit-ASCII文字の場合、これは同じ値ですが、7bit-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
string foo;
... foo.length() ...
.lengthと.sizeは同義語ですが、「長さ」という言葉の方が少しわかりやすいと思います。
std::string str("a string");
std::cout << str.size() << std::endl;
実際の文字列オブジェクトの場合:
yourstring.length();
また
yourstring.size();
文字列を入力してその長さを見つけるのが最も簡単な方法かもしれません。
// 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());
}
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;
}