수색…


소개

문자열은 일련의 문자를 나타내는 객체입니다. 표준 string 클래스는 텍스트 및 기타 문자 시퀀스를 처리 할 때 char 의 명시 적 배열을 사용하는 대신 간단하고 안전하며 다양한 방법을 제공합니다. C ++ string 클래스는 std 네임 스페이스의 일부이며 1998 년에 표준화되었습니다.

통사론

  • // 빈 문자열 선언

    std :: string s;

  • // const char * (c-string)에서 구성하기

    std :: string s ( "Hello");

    std :: string s = "Hello";

  • // 복사 생성자를 사용하여 생성

    std :: string s1 ( "Hello");

    std :: string s2 (s1);

  • // 하위 문자열로 구성

    std :: string s1 ( "Hello");

    std :: string s2 (s1, 0, 4); // s1의 0 위치에서 s2로 4 문자 복사

  • // 문자 버퍼로 구성

    std :: string s1 ( "Hello World");
    std :: string s2 (s1, 5); // s1의 처음 5 문자를 s2에 복사합니다.

  • // fill 생성자를 사용하여 생성 (char 만)

    std :: string s (5, 'a'); // s는 aaaaa를 포함합니다.

  • // 범위 생성자와 반복자를 사용하여 구성

    std :: string s1 ( "Hello World");

    std :: string s2 (s1.begin (), s1.begin () + 5); // s1의 처음 5 문자를 s2에 복사합니다.

비고

std::string 사용하기 전에 다른 헤더 (예 : iostream )에 포함되지 않은 함수 / 연산자 / 오버로드를 포함하므로 헤더 string 포함해야합니다.


nullptr과 함께 const char * 생성자를 사용하면 정의되지 않은 동작이 발생합니다.

std::string oops(nullptr);
std::cout << oops << "\n";

이 메소드 at index >= size() 경우 std::out_of_range 예외 at throw합니다.

operator[] 의 동작은 조금 더 복잡합니다. 모든 경우에 index > size() 일 때 정의되지 않은 동작을하지만 index == size() :

C ++ 11
  1. 비 const 문자열에서 동작은 정의되지 않습니다 .
  2. const 문자열에서 값이 CharT() ( null 문자) 인 문자에 대한 참조가 반환됩니다.
C ++ 11
  1. 값이 CharT() ( null 문자) 인 문자에 대한 참조가 반환됩니다.
  2. 이 참조를 수정하는 것은 정의되지 않은 동작 입니다.

사용하는 대신 C ++ (14) 이후, "foo" , 사용하는 것이 좋습니다 "foo"s 로, s A는 사용자 정의 문자 접미사 회심, const char* "foo" 하는 std::string "foo" .

참고 : 네임 스페이스 std::string_literals 또는 std::literals 을 사용하여 리터럴 sstd::string_literals 합니다.

파편

std::string::substr 을 사용하여 문자열을 분할합니다. 이 멤버 함수에는 두 가지 변형이 있습니다.

첫 번째는 반환 된 하위 문자열을 시작해야하는 시작 위치 를 취합니다. 시작 위치는 (0, str.length()] 범위에서 유효해야합니다.

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(11); // "bar and world!"

두 번째는 새 하위 문자열의 시작 위치와 전체 길이 를 취합니다. 길이에 관계없이 하위 문자열은 소스 문자열의 끝을 지나치지 않습니다.

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(15, 3); // "and"

당신은 또한 호출 할 수 있습니다 substr 문자열의 정확한 복사본이 반환이 경우, 인수없이

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(); // "Hello foo, bar and world!"

문자열 교체

위치 별 교체

(A)의 일부를 교체하려면 std::string 당신이 방법을 사용할 수 있습니다 replace 에서 std::string .

replace 에는 많은 유용한 오버로드가 있습니다.

//Define string
std::string str = "Hello foo, bar and world!";
std::string alternate = "Hello foobar";

//1)
str.replace(6, 3, "bar"); //"Hello bar, bar and world!"

//2)
str.replace(str.begin() + 6, str.end(), "nobody!"); //"Hello nobody!"

//3)
str.replace(19, 5, alternate, 6, 6); //"Hello foo, bar and foobar!"
C ++ 14
//4)
str.replace(19, 5, alternate, 6); //"Hello foo, bar and foobar!"
//5)
str.replace(str.begin(), str.begin() + 5, str.begin() + 6, str.begin() + 9);
//"foo foo, bar and world!"

//6)
str.replace(0, 5, 3, 'z'); //"zzz foo, bar and world!"

//7)
str.replace(str.begin() + 6, str.begin() + 9, 3, 'x'); //"Hello xxx, bar and world!"
C ++ 11
//8)
str.replace(str.begin(), str.begin() + 5, { 'x', 'y', 'z' }); //"xyz foo, bar and world!"

문자열의 어커런스를 다른 문자열로 바꾸기

의 첫 발생 교체 replacewithstr :

std::string replaceString(std::string str,
                          const std::string& replace,
                          const std::string& with){
    std::size_t pos = str.find(replace);
    if (pos != std::string::npos)
        str.replace(pos, replace.length(), with);
    return str;
}

모든 replace 항목을 str : with replace :

std::string replaceStringAll(std::string str,
                             const std::string& replace,
                             const std::string& with) {
    if(!replace.empty()) {
        std::size_t pos = 0;
        while ((pos = str.find(replace, pos)) != std::string::npos) {
            str.replace(pos, replace.length(), with);
            pos += with.length();
        }
    }
    return str;
}

연쇄

오버로드 된 ++= 연산자를 사용하여 std::string 연결할 수 있습니다. + 연산자 사용 :

std::string hello = "Hello";
std::string world = "world";
std::string helloworld = hello + world; // "Helloworld"

+= 연산자 사용 :

std::string hello = "Hello";
std::string world = "world";
hello += world; // "Helloworld"

문자열 리터럴을 포함하여 C 문자열을 추가 할 수도 있습니다.

std::string hello = "Hello";
std::string world = "world";
const char *comma = ", ";
std::string newhelloworld = hello + comma + world + "!"; // "Hello, world!"

push_back() 을 사용하여 개별 char 을 푸시 push_back() 수도 있습니다.

std::string s = "a, b, ";
s.push_back('c'); // "a, b, c"

append() 도 있는데, 이는 += 와 거의 같습니다 :

std::string app = "test and ";
app.append("test"); // "test and test"

캐릭터 액세스

std::string 에서 문자를 추출하는 데는 여러 가지 방법이 있으며 각각은 미묘하게 다릅니다.

std::string str("Hello world!");

연산자 [] (n)

인덱스 n의 문자에의 참조를 돌려줍니다.

std::string::operator[] 는 bounds-checked가 아니며 예외를 throw하지 않습니다. 호출자는 인덱스가 문자열 범위 내에 있다고 주장 할 책임이 있습니다.

char c = str[6]; // 'w'

at (n)

인덱스 n의 문자에의 참조를 돌려줍니다.

std::string::at 체크 된 경계이며, 인덱스가 문자열의 범위 내에 있지 않으면 std::out_of_range 를 throw합니다.

char c = str.at(7); // 'o'
C ++ 11

주 : 문자열이 비어 있으면이 두 예제 모두 정의되지 않은 동작 을 초래합니다.


앞()

최초의 캐릭터에의 참조를 돌려줍니다.

char c = str.front(); // 'H'

뒤로()

마지막 문자에 대한 참조를 반환합니다.

char c = str.back(); // '!'

토큰 화하다

런타임에 가장 비싼 것부터 가장 비싼 것까지 나열 :

  1. str::strtok 은 토큰 화 방법 중 가장 저렴한 표준이며 토큰 사이에서 구분 기호를 수정할 수 있지만 현대 C ++에서는 3 가지 어려움이 있습니다.

    • std::strtok 는 동시에 여러 strings 에서 사용할 수 없습니다 (일부 구현은 다음을 지원하기 위해 확장됩니다 : strtok_s )
    • 동일한 이유로 std::strtok 은 여러 스레드에서 동시에 사용할 수 없습니다 (그러나 구현 정의 될 수 있습니다. 예를 들면 Visual Studio의 구현은 스레드로부터 안전합니다 )
    • std::strtok 호출하면 std::string 을 조작하여 const string , const char* 또는 리터럴 문자열에 사용할 수 없으므로 std::strtok 로 토큰 화하거나 std::string 누가 내용을 보존 할 필요가 있는지, 입력은 복사되어야하고, 그 다음 복사본은

    일반적으로 이러한 옵션 비용은 토큰의 할당 비용에 숨겨져 있지만, 가장 저렴한 알고리즘이 필요하고 std::strtok 의 어려움이 극복되지 않는 경우에는 손 - 회전 솔루션을 고려하십시오.

// String to tokenize
std::string str{ "The quick brown fox" };
// Vector to store tokens
vector<std::string> tokens;

for (auto i = strtok(&str[0], " "); i != NULL; i = strtok(NULL, " "))
    tokens.push_back(i);

실제 예제

  1. std::istream_iterator 는 스트림의 추출 연산자를 반복적으로 사용합니다. 입력 std::string 이 공백으로 구분 된 경우이 문제를 제거하여 std::strtok 옵션을 확장하여 인라인 토큰 화를 허용함으로써 const vector<string> 생성을 지원하고 여러 줄 공백 문자 구분 :
// String to tokenize
const std::string str("The  quick \tbrown \nfox");
std::istringstream is(str);
// Vector to store tokens
const std::vector<std::string> tokens = std::vector<std::string>(
                                        std::istream_iterator<std::string>(is),
                                        std::istream_iterator<std::string>());

실제 예제

  1. std::regex_token_iterator 는 반복적으로 토큰 화하기 위해 std::regex 를 사용합니다. 더 유연한 구분 기호 정의를 제공합니다. 예를 들어, 구분되지 않은 쉼표와 공백은 다음과 같습니다.
C ++ 11
// String to tokenize
const std::string str{ "The ,qu\\,ick ,\tbrown, fox" };
const std::regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
// Vector to store tokens
const std::vector<std::string> tokens{ 
    std::sregex_token_iterator(str.begin(), str.end(), re, 1), 
    std::sregex_token_iterator() 
};

실제 예제

자세한 내용은 regex_token_iterator 예제 를 참조하십시오.

(const) char * 로의 변환

std::string 의 데이터에 대한 const char* 액세스를 얻으려면 문자열의 c_str() 멤버 함수를 사용할 수 있습니다. 포인터는 std::string 오브젝트가 범위 내에 있고 변경되지 않은 상태에서만 유효하다는 것을 명심하십시오. 즉, 오브젝트에 대해 const 메소드 만 호출 될 수 있습니다.

C ++ 17

data() 멤버 함수를 사용하여 std::string 객체의 데이터를 조작하는 데 사용할 수있는 수정 가능한 char* 을 얻을 수 있습니다.

C ++ 11

수정 가능한 char* 은 첫 번째 문자의 주소 인 &s[0] 을 사용하여 얻을 수도 있습니다. C ++ 11에서는 잘 구성된 null로 끝나는 문자열을 보장합니다. 참고 &s[0] 경우에서도 형성된다 s 반면, 비어 &s.front() 경우 정의되지 s 비어있다.

C ++ 11
std::string str("This is a string.");
const char* cstr = str.c_str(); // cstr points to: "This is a string.\0"
const char* data = str.data();  // data points to: "This is a string.\0"
std::string str("This is a string.");

// Copy the contents of str to untie lifetime from the std::string object
std::unique_ptr<char []> cstr = std::make_unique<char[]>(str.size() + 1);

// Alternative to the line above (no exception safety):
// char* cstr_unsafe = new char[str.size() + 1];

std::copy(str.data(), str.data() + str.size(), cstr);
cstr[str.size()] = '\0'; // A null-terminator needs to be added

// delete[] cstr_unsafe;
std::cout << cstr.get();

문자열에서 문자 찾기

문자 또는 다른 문자열을 찾으려면 std::string::find 사용할 수 있습니다. 첫 번째 일치의 첫 번째 문자의 위치를 ​​반환합니다. 일치하는 항목이 std::string::npos 반환합니다.

std::string str = "Curiosity killed the cat";
auto it = str.find("cat");

if (it != std::string::npos)
    std::cout << "Found at position: " << it << '\n';
else
    std::cout << "Not found!\n";

게재 순위 : 21


검색 기능은 다음 기능을 통해 더욱 확장됩니다.

find_first_of     // Find first occurrence of characters 
find_first_not_of // Find first absence of characters 
find_last_of      // Find last occurrence of characters 
find_last_not_of  // Find last absence of characters 

이러한 함수를 사용하면 문자열의 끝에서 문자를 검색 할 수있을뿐만 아니라 부정적인 경우 (즉, 문자열에없는 문자)를 찾을 수 있습니다. 다음은 그 예입니다.

std::string str = "dog dog cat cat";
std::cout << "Found at position: " << str.find_last_of("gzx") << '\n';

게재 순위 : 6

참고 : 위 함수는 하위 문자열을 검색하지 않고 검색 문자열에 포함 된 문자를 검색합니다. 이 경우 'g' 의 마지막 항목은 위치 6 에서 발견되었습니다 (다른 문자는 발견되지 않음).

시작 / 끝 부분의 문자 다듬기

이 예제에는 헤더 <algorithm> , <locale><utility> 합니다.

C ++ 11

시퀀스 또는 문자열을 자르 려면 특정 술어와 일치하는 모든 앞뒤의 요소 (또는 문자)를 제거하는 것을 의미합니다. 우리는 어떤 요소를 움직이는 것을 포함하지 않기 때문에 처음으로 후미 요소를 다듬은 다음 주요 요소를 잘라냅니다. 아래의 일반화는 모든 유형의 std::basic_string (예 : std::stringstd::wstring ) 및 실수로 시퀀스 컨테이너 (예 : std::vectorstd::list )에서 작동합니다.

template <typename Sequence, // any basic_string, vector, list etc.
          typename Pred>     // a predicate on the element (character) type
Sequence& trim(Sequence& seq, Pred pred) {
    return trim_start(trim_end(seq, pred), pred);
}

후행 요소를 자르려면 술어와 일치하지 않는 마지막 요소를 찾아서 거기에서 지우는 작업이 필요합니다.

template <typename Sequence, typename Pred>
Sequence& trim_end(Sequence& seq, Pred pred) {
    auto last = std::find_if_not(seq.rbegin(),
                                 seq.rend(),
                                 pred);
    seq.erase(last.base(), seq.end());
    return seq;
}

주요 요소를 자르려면 술어와 일치하지 않는 첫 번째 요소를 찾아서 지우는 것이 포함됩니다.

template <typename Sequence, typename Pred>
Sequence& trim_start(Sequence& seq, Pred pred) {
    auto first = std::find_if_not(seq.begin(),
                                  seq.end(),
                                  pred);
    seq.erase(seq.begin(), first);
    return seq;
}

위에서 std::string 에서 공백을 제거하기 위해 std::isspace() 함수를 술어로 사용할 수 있습니다.

std::string& trim(std::string& str, const std::locale& loc = std::locale()) {
    return trim(str, [&loc](const char c){ return std::isspace(c, loc); });
}

std::string& trim_start(std::string& str, const std::locale& loc = std::locale()) {
    return trim_start(str, [&loc](const char c){ return std::isspace(c, loc); });
}

std::string& trim_end(std::string& str, const std::locale& loc = std::locale()) {
    return trim_end(str, [&loc](const char c){ return std::isspace(c, loc); });
}

비슷하게 std::wstring 등에 std::iswspace() 함수를 사용할 수 있습니다.

트리밍 된 복사본 인 시퀀스를 만들려면 별도의 함수를 사용할 수 있습니다.

template <typename Sequence, typename Pred>
Sequence trim_copy(Sequence seq, Pred pred) { // NOTE: passing seq by value
    trim(seq, pred);
    return seq;
}

언어 사전 비교

두 개의 std::string== ,! != , < , <= , >>= 연산자를 사용하여 사전 식으로 비교할 수 있습니다.

std::string str1 = "Foo";
std::string str2 = "Bar";

assert(!(str1 < str2));
assert(str > str2);
assert(!(str1 <= str2));
assert(str1 >= str2);
assert(!(str1 == str2));
assert(str1 != str2);

이 모든 함수는 기본 std::string::compare() 메서드를 사용하여 비교를 수행하고 편의상 부울 값을 반환합니다. 이러한 함수의 동작은 실제 구현에 관계없이 다음과 같이 해석 될 수 있습니다.

  • 연산자 == :

    str1.length() == str2.length() 와 각 문자 쌍이 일치하면 true 를 반환하고 그렇지 않으면 false 를 반환 true .

  • 연산자 != :

    str1.length() != str2.length() 또는 한 문자 쌍이 일치하지 않으면 true 반환하고 그렇지 않으면 false 반환합니다.

  • 연산자 < 또는 연산자 > :

    첫 번째 다른 문자 쌍을 찾아 비교 한 다음 부울 결과를 반환합니다.

  • 연산자 <= 또는 연산자 >= :

    첫 번째 다른 문자 쌍을 찾아 비교 한 다음 부울 결과를 반환합니다.

주 : 문자 쌍 이라는 용어는 동일한 위치의 두 문자열에서 해당 문자를 의미합니다. 더 나은 이해를 위해 두 예제 문자열이 str1str2 이고 길이가 각각 nm 인 경우 두 문자열의 문자 쌍은 각각 str1[i]str2[i] 쌍을 의미합니다. 여기서 i = 0, 1, 2 str2[i] .., max (n, m) 이다. 해당 문자가 존재하지 않는 i 에 대해, 즉 in 또는 m 보다 크거나 같으면 가장 낮은 값으로 간주됩니다.


다음은 < :를 사용하는 예제입니다.

std::string str1 = "Barr";
std::string str2 = "Bar";

assert(str2 < str1);

단계는 다음과 같습니다.

  1. 첫 번째 문자 인 'B' == 'B' 비교해보십시오.
  2. 두 번째 문자 인 'a' == 'a' 비교해보십시오.
  3. 세 번째 문자 인 'r' == 'r' 비교해보십시오.
  4. str1 범위는 여전히 문자를 가지고있는 반면 str2 범위는 고갈되었습니다. 따라서 str2 < str1 입니다.

std :: wstring 로의 변환

C ++에서 문자 시퀀스는 기본 문자 유형으로 std::basic_string 클래스를 특수화하여 표현됩니다. 표준 라이브러리에 의해 정의 된 두 개의 주요 콜렉션은 std::stringstd::wstring :

  • std::stringchar 유형의 요소로 작성됩니다.

  • std::wstringwchar_t 유형의 요소로 빌드됩니다.

두 유형간에 변환하려면 wstring_convert 사용 wstring_convert .

#include <string>
#include <codecvt>
#include <locale>

std::string input_str = "this is a -string-, which is a sequence based on the -char- type.";
std::wstring input_wstr = L"this is a -wide- string, which is based on the -wchar_t- type.";

// conversion
std::wstring str_turned_to_wstr = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(input_str);

std::string wstr_turned_to_str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(input_wstr);

유용성 및 / 또는 가독성을 개선하기 위해 변환을 수행하는 함수를 정의 할 수 있습니다.

#include <string>
#include <codecvt>
#include <locale>

using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;

std::string to_string(std::wstring wstr)
{
    return strconverter.to_bytes(wstr);
}

std::wstring to_wstring(std::string str)
{
    return strconverter.from_bytes(str);
}

샘플 사용법 :

std::wstring a_wide_string = to_wstring("Hello World!");

확실히 std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!") 보다 읽기 std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!") .


charwchar_t 는 인코딩을 의미하지 않으며 크기를 바이트로 표시하지 않습니다. 예를 들어, wchar_t 는 일반적으로 2 바이트 데이터 유형으로 구현되며 일반적으로 Windows에서 UTF-16으로 인코딩 된 데이터 (또는 Windows 2000 이전 버전에서는 UCS-2)를 포함하고 UTF-32를 사용하여 인코딩 된 4 바이트 데이터 유형으로 리눅스. 이것은 C ++ 11에서 소개되었으며 각각 UTF16 또는 UTF32 "문자"(또는보다 정확하게는 코드 포인트 )를 담을만큼 충분히 클 수있는 새로운 유형의 char16_tchar32_t 와는 대조적입니다.

std :: string_view 클래스 사용하기

C ++ 17

C ++ 17에서는 std::string_view 소개합니다. std::string_viewconst char 의 소유하지 않은 범위이며 포인터 또는 포인터와 길이의 쌍으로 구현됩니다. 수정 불가능한 문자열 데이터가 필요한 함수의 경우보다 우수한 매개 변수 유형입니다. C ++ 17 이전에는 다음과 같은 세 가지 옵션이있었습니다.

void foo(std::string const& s);      // pre-C++17, single argument, could incur
                                     // allocation if caller's data was not in a string
                                     // (e.g. string literal or vector<char> )

void foo(const char* s, size_t len); // pre-C++17, two arguments, have to pass them
                                     // both everywhere

void foo(const char* s);             // pre-C++17, single argument, but need to call
                                     // strlen()

template <class StringT>
void foo(StringT const& s);          // pre-C++17, caller can pass arbitrary char data
                                     // provider, but now foo() has to live in a header

이들 모두는 다음으로 대체 될 수 있습니다 :

void foo(std::string_view s);        // post-C++17, single argument, tighter coupling
                                     // zero copies regardless of how caller is storing
                                     // the data

std::string_view 기본 데이터를 수정할 수 없습니다 .

string_view 는 불필요한 사본을 피하고자 할 때 유용합니다.

함수의 일부가 다르게 동작하지만 std::string 이 수행하는 유용한 하위 집합을 제공합니다.

std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; //A really long string

//Bad way - 'string::substr' returns a new string (expensive if the string is long)
std::cout << str.substr(15, 10) << '\n';

//Good way - No copies are created!
std::string_view view = str;

// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';

각 캐릭터 반복

C ++ 11

std::string 은 반복자를 지원하므로 원거리 기반 루프를 사용하여 각 문자를 반복 할 수 있습니다.

std::string str = "Hello World!";
for (auto c : str)
    std::cout << c;

"전통적인" for 루프를 사용하여 모든 문자를 반복 할 수 있습니다.

std::string str = "Hello World!";
for (std::size_t i = 0; i < str.length(); ++i)
    std::cout << str[i];

정수 / 부동 소수점 유형으로 변환

숫자를 포함하는 std::string 은 변환 함수를 사용하여 정수 유형 또는 부동 소수점 유형으로 변환 될 수 있습니다.

이러한 모든 기능은 즉시이 숫자가 아닌 문자가 발생할로 입력 문자열을 구문 분석을 중단합니다, 그래서 "123abc" 로 변환됩니다 123 .


함수의 std::ato* 패밀리는 C 스타일 문자열 (문자 배열)을 정수 또는 부동 소수점 유형으로 변환합니다.

std::string ten = "10";

double num1 = std::atof(ten.c_str());
int num2 = std::atoi(ten.c_str());
long num3 = std::atol(ten.c_str());
C ++ 11
long long num4 = std::atoll(ten.c_str());

그러나이 함수는 문자열을 구문 분석하지 못하면 0 을 반환하므로 사용하지 않는 것이 좋습니다. 때문에 나쁜 0 예를 들어, 입력 문자열이 "0"인 경우에도 유효한 결과가 될 수있는, 그래서 전환이 실제로 실패를 결정하는 것은 불가능하다.

새로운 std::sto* 함수 군은 std::string 을 정수형 또는 부동 소수점 형으로 변환하고 입력을 구문 분석 할 수없는 경우 예외를 throw합니다. 가능한 경우 다음 함수를 사용해야합니다 .

C ++ 11
std::string ten = "10";

int num1 = std::stoi(ten);
long num2 = std::stol(ten);
long long num3 = std::stoll(ten);

float num4 = std::stof(ten);
double num5 = std::stod(ten);
long double num6 = std::stold(ten);

또한이 함수는 std::ato* 계열과 달리 8 진수 및 16 진수 문자열도 처리합니다. 두 번째 매개 변수는 입력 문자열에서 첫 번째 변환되지 않은 문자 (여기에 설명되지 않음)에 대한 포인터이며 세 번째 매개 변수는 사용할 기준입니다. 0 은 8 진수 ( 0 시작)와 16 진수 ( 0x 또는 0X 시작)의 자동 감지이며, 다른 모든 값은 사용할 기본입니다

std::string ten = "10";
std::string ten_octal = "12";
std::string ten_hex = "0xA";

int num1 = std::stoi(ten, 0, 2); // Returns 2
int num2 = std::stoi(ten_octal, 0, 8); // Returns 10
long num3 = std::stol(ten_hex, 0, 16);  // Returns 10
long num4 = std::stol(ten_hex);  // Returns 0
long num5 = std::stol(ten_hex, 0, 0); // Returns 10 as it detects the leading 0x

문자 인코딩 간의 변환

C ++ 11에서는 인코딩 간의 변환이 쉽고 대부분의 컴파일러는 <codecvt><locale> 헤더를 통해 플랫폼 간 방식으로 처리 할 수 ​​있습니다.

#include <iostream>
#include <codecvt>
#include <locale>
#include <string>
using namespace std;

int main() {
    // converts between wstring and utf8 string
    wstring_convert<codecvt_utf8_utf16<wchar_t>> wchar_to_utf8;
    // converts between u16string and utf8 string
    wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> utf16_to_utf8;
    
    wstring wstr = L"foobar";
    string utf8str = wchar_to_utf8.to_bytes(wstr);
    wstring wstr2 = wchar_to_utf8.from_bytes(utf8str);
    
    wcout << wstr << endl;
    cout << utf8str << endl;
    wcout << wstr2 << endl;
    
    u16string u16str = u"foobar";
    string utf8str2 = utf16_to_utf8.to_bytes(u16str);
    u16string u16str2 = utf16_to_utf8.from_bytes(utf8str2);
    
    return 0;
}

비주얼 스튜디오 2015는 이러한 변환에 대한 지원을 제공하지만 염두 버그 자신의 라이브러리 구현을 위해 다른 템플릿을 사용하는 데 필요한 wstring_convert 를 처리 할 때 char16_t :

using utf16_char = unsigned short;
wstring_convert<codecvt_utf8_utf16<utf16_char>, utf16_char> conv_utf8_utf16;

void strings::utf16_to_utf8(const std::u16string& utf16, std::string& utf8)
{
  std::basic_string<utf16_char> tmp;
  tmp.resize(utf16.length());
  std::copy(utf16.begin(), utf16.end(), tmp.begin());
  utf8 = conv_utf8_utf16.to_bytes(tmp);
}
void strings::utf8_to_utf16(const std::string& utf8, std::u16string& utf16)
{ 
  std::basic_string<utf16_char> tmp = conv_utf8_utf16.from_bytes(utf8);
  utf16.clear();
  utf16.resize(tmp.length());
  std::copy(tmp.begin(), tmp.end(), utf16.begin());
}

문자열이 다른 문자열의 접두어인지 확인

C ++ 14

C ++ 14에서는 두 범위에서 첫 번째로 일치하지 않는 쌍을 반환하는 std::mismatch 쉽게 수행 할 수 있습니다.

std::string prefix = "foo";
std::string string = "foobar";

bool isPrefix = std::mismatch(prefix.begin(), prefix.end(),
    string.begin(), string.end()).first == prefix.end();

C ++ 14 이전에는 mismatch() 의 범위와 반 버전이 있었지만 두 번째 문자열이 두 번째 문자열보다 짧은 경우 안전하지 않습니다.

C ++ 14

우리는 std::mismatch() 의 range-and-half 버전을 여전히 사용할 수 있지만, 먼저 첫 번째 문자열이 두 번째 문자열만큼 크다는 것을 확인해야합니다.

bool isPrefix = prefix.size() <= string.size() &&
    std::mismatch(prefix.begin(), prefix.end(),
        string.begin(), string.end()).first == prefix.end();
C ++ 17

std::string_view 사용하면 할당 오버 헤드 나 복사본을 만들 필요없이 직접 비교할 수 있습니다.

bool isPrefix(std::string_view prefix, std::string_view full)
{
    return prefix == full.substr(0, prefix.size());
}

std :: string으로 변환 중

std::ostringstream 은 객체를 std::ostringstream 객체 (스트림 삽입 연산자 << )에 삽입 한 다음 전체 std::ostringstreamstd::ostringstream 으로 변환하여 스트리밍 가능한 유형을 문자열 표현으로 변환하는 데 사용할 수 있습니다 std::string .

int 의 경우 :

#include <sstream>

int main()
{
    int val = 4;
    std::ostringstream str;
    str << val;
    std::string converted = str.str();
    return 0;
}

자신 만의 변환 함수를 작성하면 간단합니다.

template<class T>
std::string toString(const T& x)
{
  std::ostringstream ss;
  ss << x;
  return ss.str();
}

성능이 중요한 코드에는 적합하지 않습니다.

원하는 경우 사용자 정의 클래스는 스트림 삽입 연산자를 구현할 수 있습니다.

std::ostream operator<<( std::ostream& out, const A& a )
{
    // write a string representation of a to out
    return out; 
}
C ++ 11

스트림을 제외하고 C ++ 11 이후에는 모든 기본 유형에 대해 오버로드 된 std::to_string (및 std::to_wstring ) 함수를 사용할 수 있으며 해당 매개 변수의 문자열 표현을 반환합니다.

std::string s = to_string(0x12f3);  // after this the string s contains "4851"


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow