programing

std:: 문자열을 const char* 또는 char*로 변환하는 방법

magicmemo 2023. 4. 21. 20:28
반응형

std:: 문자열을 const char* 또는 char*로 변환하는 방법

요?std::string a까지char* ★★★const char*

를 필요한 함수에 전달하고 싶은 경우const char *, 다음을 사용할 수 있습니다.

std::string str;
const char * c = str.c_str();

하지 않은 것이 char *, 호출:

std::string str;
char * c = str.data();

.data()C++17이면 된다.전에 ㅇㅇㅇㅇㅇ를 할 수 .&str[0].

「 」의는, 해 주세요.std::stringconst,.data()const char * ""와 같이 ""와 같이"".c_str().

문자열이 파괴되거나 메모리를 재할당하면 포인터가 비활성화됩니다.

가 눌 문자열을 는 "" "null" "null" "null" "null" "null" "null" "null" "null" "null" "null" "null" "null" "null" "null" "null" "" "count" "count" "" 은 .str.size()할 수 터미네이터에는 Null이 아닌 문자를 할당할 수 없습니다.

예를 들면...

std::string x = "hello";

문자열에서 "char *" 또는 "const char*"를 가져옵니다.

x수정하지 내에 있습니다.

C++11은 모든 것을 단순화합니다.다음은 모두 같은 내부 문자열 버퍼에 대한 접근을 제공합니다.

const char* p_c_str = x.c_str();
const char* p_data  = x.data();
char* p_writable_data = x.data(); // for non-const x from C++17 
const char* p_x0    = &x[0];

      char* p_x0_rw = &x[0];  // compiles iff x is not const...

위의 모든 포인터는 동일한 값(버퍼 내의 첫 번째 문자의 주소)을 유지합니다.C++11은 명시적으로 할당된 문자열 내용 뒤에 항상 추가 NUL/0 터미네이터 문자를 유지할 것을 보증하기 때문에 빈 문자열에도 "버퍼 내의 첫 번째 문자"가 있습니다.std::string("this\0that", 9)버퍼 홀딩을 가지다"this\0that\0"를 참조해 주세요.

위의 포인터 중 하나가 지정됩니다.

char c = p[n];   // valid for n <= x.size()
                 // i.e. you can safely read the NUL at p[x.size()]

constp_writable_data 및서에서&x[0]:

p_writable_data[n] = c;
p_x0_rw[n] = c;  // valid for n <= x.size() - 1
                 // i.e. don't overwrite the implementation maintained NUL

문자열의 다른 위치에 NUL을 써도 NUL은 변경되지 않습니다.string의 »size()string에는 임의의 할 수 은 NUL에 특별히 취급되지 않습니다.이러한 NUL은, 다음의 순서에 의해서 특별한 취급을 받지 않습니다.std::string(C++03의 경우).

C++03에서는 상황이 상당히 복잡했습니다(주요 차이점이 강조 표시됨).

  • x.data()

    • const char*NUL결론짓기 위해 표준에서 요구하지 않은 문자열의 내부 버퍼(예:['h', 'e', 'l', 'l', 'o']이어 초기화되지 않았거나 가비지 값이 발생하며, 우발적인 액세스에 정의되지 않은 동작이 있습니다).
      • x.size()x[0] through를 통해.x[x.size() - 1]
      • 빈 문자열의 경우 0을 안전하게 추가할 수 있는 NULL 이외의 포인터가 보장되지만(만세!) 해당 포인터를 참조 해제해서는 안 됩니다.
  • &x[0]

    • 빈 문자열의 경우 이는 정의되지 않은 동작을 가집니다(21.3.4).
      • ::f(const char* p, size_t n) { if (n == 0) return; ...whatever... }는 안 된다f(&x[0], x.size());x.empty() 쓰세요. - 그냥 쓰세요f(x.data(), ...).
    • 이외의 경우는, 「 」에 따라서x.data()§,
      • 의 non non const x 비(비(非스톱이 되다.const char* 문자열 수 .
  • x.c_str()

    • const char*ASCIIIZ(NUL as의의 as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as as)
    • 어떤 구현이 그렇게 하도록 선택한 경우는 거의 없지만, C++03 표준은 문자열 구현에 의해 잠재적으로 NUL 종료되지 않은 버퍼로부터 NUL 종단 버퍼즉시 생성할 수 있도록 단어화되었습니다.x.data() ★★★★★★★★★★★★★★★★★」&x[0]
    • x.size()+ 1을 더하다
    • 빈 문자열(['\0')에도 안전이 보장됩니다.

외부 법률 색인 접근의 결과

어떤 방법으로든 포인터를 얻으면 위의 설명에서 보장된 문자보다 포인터에서 더 이상 메모리에 액세스해서는 안 됩니다.이를 시도하면 읽기에서도 응용 프로그램이 크래시되고 결과가 가비지될 가능성이 매우 높으며, 게다가 대규모 데이터, 스택 파손 및/또는 쓰기 보안 취약점이 발생할 가능성이 있습니다.

그 포인터들은 언제 무효가 되나요?

some에 stringstring또는 추가 용량을 예약하면 위의 방법 중 하나로 미리 반환된 포인터 값은 비활성화됩니다.이러한 방법을 다시 사용하여 다른 포인터를 얻을 수 있습니다. (규칙은 반복자가 다음 명령을 수행하는 것과 동일합니다.string

또한 스코프를 벗어나거나 아래 내용을 수정한 후에도 문자 포인터를 유효하게 하는 방법을 참조하십시오.

그렇다면, 어떤 것을 사용하는 것이 좋을까요?

부터는 C++11 을 합니다..c_str()및 ASCIIZ의 경우.data()(아래 참조)를 참조해 주세요.

C++03을 합니다..c_str()이 한.data(), 「적당하다」라고 하는 것을 선호합니다..data()에 걸쳐서&x[0]★★★★★★★★★★★...

할 수 있는 ...사용할 수 있는 프로그램을 이해하려고 한다.data()적절한 때에, 그렇지 않으면 다른 실수를 하게 될 것이다.

ASCII NUL '\0'이 하는 ASCII ..c_str()는 많은 함수에 의해 관련성이 있고 접근이 안전한 데이터의 종료를 나타내는 센티넬 값으로 사용됩니다.은 C++와 C에 모두 해당됩니다.fstream::fstream(const char* filename, ...) C와 같은 을 공유합니다.strchr() , , , , 입니다.printf().

「」C++03의 소정.c_str().data()은 언제나 하실 수 있습니다..c_str() 안 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아

  • 를 사용합니다..data()는 소스 코드를 읽고 있는 다른 프로그래머에게 데이터가 ASCIIZ가 아니거나(오히려 문자열로 데이터 블록을 저장하거나(때로는 텍스트가 아닌 경우도 있음) 데이터를 "이진" 데이터 블록으로 취급하는 다른 함수에 전달하고 있음을 전달합니다.이는 다른 프로그래머의 코드 변경이 데이터를 계속 적절하게 처리하도록 보장하는 데 중요한 통찰력이 될 수 있습니다.
  • 한정: C++03은 약간 가능성이 string 할당 및 를 몇 .NUL은 NUL로 종료된 버퍼를 준비합니다.

에 필요한 「 」 「 」 「 」 「 」 「 」 「 」).constchar* 무조건 따지지는 x.size()함수에는 ASCIIZ 입력이 필요할 수 있습니다..c_str()를 선택하는 것이 좋습니다(이 함수는 텍스트의 끝부분을 알 필요가 있기 때문에 별도의 파라미터가 아닌 경우에는 길이 제한, 센티넬 또는 일정한 예상 길이와 같은 규칙만 사용할 수 있습니다).

x (더욱 변경됨)

의 내용을 복사해야 합니다.string x에 있는 x는, 장소에 가 있습니다string 변수는 수 .x다른 범위(네임스페이스, 글로벌, 스태틱, 힙, 공유 메모리, 메모리 매핑 파일 등)에 있기 때문입니다.

하려면 , 스스 to to to to to to 。std::string x"CHANGE: "CHANGE: " 。

// USING ANOTHER STRING - AUTO MEMORY MANAGEMENT, EXCEPTION SAFE
std::string old_x = x;
// - old_x will not be affected by subsequent modifications to x...
// - you can use `&old_x[0]` to get a writable char* to old_x's textual content
// - you can use resize() to reduce/expand the string
//   - resizing isn't possible from within a function passed only the char* address

std::string old_x = x.c_str(); // old_x will terminate early if x embeds NUL
// Copies ASCIIZ data but could be less efficient as it needs to scan memory to
// find the NUL terminator indicating string length before allocating that amount
// of memory to copy into, or more efficient if it ends up allocating/copying a
// lot less content.
// Example, x == "ab\0cd" -> old_x == "ab".

// USING A VECTOR OF CHAR - AUTO, EXCEPTION SAFE, HINTS AT BINARY CONTENT, GUARANTEED CONTIGUOUS EVEN IN C++03
std::vector<char> old_x(x.data(), x.data() + x.size());       // without the NUL
std::vector<char> old_x(x.c_str(), x.c_str() + x.size() + 1);  // with the NUL

// USING STACK WHERE MAXIMUM SIZE OF x IS KNOWN TO BE COMPILE-TIME CONSTANT "N"
// (a bit dangerous, as "known" things are sometimes wrong and often become wrong)
char y[N + 1];
strcpy(y, x.c_str());

// USING STACK WHERE UNEXPECTEDLY LONG x IS TRUNCATED (e.g. Hello\0->Hel\0)
char y[N + 1];
strncpy(y, x.c_str(), N);  // copy at most N, zero-padding if shorter
y[N] = '\0';               // ensure NUL terminated

// USING THE STACK TO HANDLE x OF UNKNOWN (BUT SANE) LENGTH
char* y = alloca(x.size() + 1);
strcpy(y, x.c_str());

// USING THE STACK TO HANDLE x OF UNKNOWN LENGTH (NON-STANDARD GCC EXTENSION)
char y[x.size() + 1];
strcpy(y, x.c_str());

// USING new/delete HEAP MEMORY, MANUAL DEALLOC, NO INHERENT EXCEPTION SAFETY
char* y = new char[x.size() + 1];
strcpy(y, x.c_str());
//     or as a one-liner: char* y = strcpy(new char[x.size() + 1], x.c_str());
// use y...
delete[] y; // make sure no break, return, throw or branching bypasses this

// USING new/delete HEAP MEMORY, SMART POINTER DEALLOCATION, EXCEPTION SAFE
// see boost shared_array usage in Johannes Schaub's answer

// USING malloc/free HEAP MEMORY, MANUAL DEALLOC, NO INHERENT EXCEPTION SAFETY
char* y = strdup(x.c_str());
// use y...
free(y);

른른 a a a char* ★★★★★★★★★★★★★★★★★」const char*에서 string

그럼 에서 '( 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으, 으,으)'를 얻는 방법을 .constchar*의 「복사」로부터 된 string하지만 그걸로 뭘 할 수 있죠?무작위로 몇 가지 예를 들면...

  • C++에 '부여합니다.string 「」와 )printf("x is '%s'", x.c_str());
  • x한 버퍼에의 「」 「」 「」 「」 「」 「」 「」).strncpy(callers_buffer, callers_buffer_size, x.c_str())O에 "I/O")for (const char* p = x.c_str(); *p; ++p) *p_device = *p;)
  • x텍스트가 배열에 의 "ASCIIZ")strcat(other_buffer, x.c_str()) - 해 주세요할 필요가 있습니다).strncat)
  • const char* ★★★★★★★★★★★★★★★★★」char*이유로 API를 C C를 않을 입니다.)std::string는 않아요.string★★★★★★★★★★★★★★★★★★★」
    • 의 「로컬」 이 있는 해 주세요.string입니다.
    • 컴파일 되어 있는 중 는 다른 공유 오브젝트를 으로 합니다.std::string를 들어및 네이티브은 데이터를 (STLport)로 할 수 .

하다를 사용하세요..c_str()의 for의 const char *.

하시면 됩니다.&mystring[0]char *갓챠제로 끝의 문자열이 반드시 표시되는 것은 아니며 문자열의 크기를 변경할 수도 없습니다.특히 문자열 끝에 문자를 추가하지 않도록 주의해야 합니다. 그렇지 않으면 버퍼 오버런(및 크래시 가능성 있음)이 발생합니다.

까지 모든 는 C++11의 모든 이 C++11에 포함되어 있습니다.std::string"&s[0]"는 std:: 문자열의 연속된 문자를 가리키고 있습니까?를 참조해 주십시오.

: " " " " " 입니다.string 버퍼를하여 저장한 포인터를 비활성화합니다.member는 저장된 를 모두 합니다.즉시 사용할 수 있도록 최선을 다하고 폐기하십시오.즉시 사용한 후 폐기하는 것이 가장 좋습니다.

C++17

C++17(향후 표준)에 의해 템플릿의 개요가 변경됩니다.basic_string adding a non const overload of 비항상 과부하 추가data():

charT* data() noexcept;

반품:[0,size()]의 각 i에 대해 p + i == & laughters가 되는 포인터 p.


CharT const *부에서std::basic_string<CharT>

std::string const cstr = { "..." };
char const * p = cstr.data(); // or .c_str()

CharT *부에서std::basic_string<CharT>

std::string str = { "..." };
char * p = str.data();

C++11

CharT const *부에서std::basic_string<CharT>

std::string str = { "..." };
str.c_str();

CharT *부에서std::basic_string<CharT>

C++11 이후 표준에는 다음과 같이 기재되어 있습니다.

  1. The char-like objects in a 그 안에 있는 차체와 같은 오브젝트basic_string오브젝트는 인접하여 저장해야 합니다. 임의의 ,에 basic_string객체 물s, , the identity , 아이덴티티&*(s.begin() + n) == &*s.begin() + n shall hold for all values of 모든 값에 대해 유지되어야 한다.n such that 그렇게 해서0 <= n < s.size().

  1. const_reference operator[](size_type pos) const;
    reference operator[](size_type pos);

    반환합니다.*(begin() + pos) if 한다면pos < size(), , otherwise a reference to an object of type , 그 이외의 경우 유형 객체에 대한 참조CharT with value 가치 있게CharT(); 참조된 값이 수정되지 않아야 합니다.; ; 참조된 값은 수정할 수 없습니다.


  1. const charT* c_str() const noexcept;
    const charT* data() const noexcept;

    반환합니다.반품: A pointer p such that 포인터 p는 다음과 같습니다.p + i == &operator[](i) for each 각각에 대해서i in 에[0,size()].

고정되지 않은 문자 포인터를 얻는 방법은 여러 가지가 있습니다.

1. C++11의 연속 스토리지를 사용한다.

std::string foo{"text"};
auto p = &*foo.begin();

프로

  • 심플하고 짧은
  • 고속(복사가 포함되지 않는 방법만 해당)

단점

  • 최종 종'\0'비건설 메모리의 일부가 변경되지 않습니다.변경할 수 없습니다.이치노

. 2. 용 2std::vector<CharT>

std::string foo{"text"};
std::vector<char> fcv(foo.data(), foo.data()+foo.size()+1u);
auto p = fcv.data();

프로

  • 간단하죠.
  • 자동 메모리 처리
  • 역학

단점

  • 문자열 복사 필요

. 3. 용용을 하세요.std::array<CharT, N>N★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★♪

std::string foo{"text"};
std::array<char, 5u> fca;
std::copy(foo.data(), foo.data()+foo.size()+1u, fca.begin());

프로

  • 간단하죠.
  • 스택 메모리 처리

단점

  • 스태틱
  • 문자열 복사 필요

4. 스토리지 자동 삭제에 의한 원시 메모리 할당

std::string foo{ "text" };
auto p = std::make_unique<char[]>(foo.size()+1u);
std::copy(foo.data(), foo.data() + foo.size() + 1u, &p[0]);

프로

  • 메모리 설치 공간 절약
  • 자동 삭제
  • 간단하죠.

단점

  • 문자열 복사 필요
  • 정적(동적 사용에는 더 많은 코드가 필요)
  • 벡터 또는 어레이보다 기능이 적다

5. 수동 조작에 의한 원시 메모리 할당

std::string foo{ "text" };
char * p = nullptr;
try
{
  p = new char[foo.size() + 1u];
  std::copy(foo.data(), foo.data() + foo.size() + 1u, p);
  // handle stuff with p
  delete[] p;
}
catch (...)
{
  if (p) { delete[] p; }
  throw;
}

프로

  • 최대 '제어'

단점

  • 문자열 복사 필요
  • 오류에 대한 최대 책임/취약성
  • 복잡한

이것만 봐주세요.

string str1("stackoverflow");
const char * str2 = str1.c_str();

「」, 「」가 해 주세요.const char *.

char *하다, 사용하다strcpy to복에 베끼다charmanager.manager로 하다

는 a는로로로 를 얻을 수 있는 .char*입력으로 사용합니다.

저는 이런 문제에 대처하기 위해 작은 반을 만들어 RAII 숙어를 도입했습니다.

class DeepString
{
        DeepString(const DeepString& other);
        DeepString& operator=(const DeepString& other);
        char* internal_; 
    
    public:
        explicit DeepString( const string& toCopy): 
            internal_(new char[toCopy.size()+1]) 
        {
            strcpy(internal_,toCopy.c_str());
        }
        ~DeepString() { delete[] internal_; }
        char* str() const { return internal_; }
        const char* c_str()  const { return internal_; }
};

다음과 같이 사용할 수 있습니다.

void aFunctionAPI(char* input);

//  other stuff

aFunctionAPI("Foo"); //this call is not safe. if the function modified the 
                     //literal string the program will crash
std::string myFoo("Foo");
aFunctionAPI(myFoo.c_str()); //this is not compiling
aFunctionAPI(const_cast<char*>(myFoo.c_str())); //this is not safe std::string 
                                                //implement reference counting and 
                                                //it may change the value of other
                                                //strings as well.
DeepString myDeepFoo(myFoo);
aFunctionAPI(myFoo.str()); //this is fine

는 반을 the는 the the the 라고 불렀습니다.DeepString은 깊고 한 카피(카피)를이다.DeepString을 이용하다)

char* result = strcpy((char*)malloc(str.length()+1), str.c_str());

c++ std 문자열에서 C 스타일 문자열로 변환하는 것은 매우 간단합니다.

위해 는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★.string::copystd 문자열을 C 스타일 문자열로 쉽게 변환하는 함수입니다.레퍼런스

string::copy parameters의 .

  1. 문자 문자열 포인터
  2. 문자열 크기, 복사되는 문자 수
  3. 위치, 문자 복사가 시작되는 위치

또 하나 중요한 건

이 함수는 작업 종료 시 null 문자를 추가하지 않습니다.그래서 우리는 그것을 수동으로 넣어야 합니다.

코드 테스트는 다음과 같습니다.

// char string
char chText[20];

// c++ string
string text =  "I am a Programmer";

// conversion from c++ string to char string
// this function does not append a null character at the end of operation
text.copy(chText, text.size(), 0);

// we need to put it manually
chText[text.size()] = '\0';

// below statement prints "I am a Programmer"
cout << chText << endl;

반대로, C 스타일 문자열에서 C++ 표준 문자열로 변환하는 것이 훨씬 쉽습니다.

C 스타일 문자열에서 C++ std 문자열로 변환할 수 있는 방법은 세 가지가 있습니다.

첫 번째는 컨스트럭터를 사용하는 것입니다.

char chText[20] = "I am a Programmer";
// using constructor
string text(chText);

번째는 '할 수 없다'입니다.string::assign

// char string
char chText[20] = "I am a Programmer";

// c++ string
string text;

// convertion from char string to c++ string
// using assign function
text.assign(chText);

세 번째는 할당 연산자(=)로, 문자열 클래스는 연산자 오버로드를 사용합니다.

// char string
char chText[20] = "I am a Programmer";

// c++ string
// convertion from char string to c++ string using assignment operator overloading
string text = chText;

세 번째는 다음과 같이 쓸 수도 있습니다.

// char string
char chText[20] = "I am a Programmer";

// c++ string
string text;


// convertion from char string to c++ string
text = chText;

예를 들어 string str="stack";

1) 문자열을 char*로 변환

  char* s_rw=&str[0]; 

위의 char*(s_rw)는 읽기 쉽고 쓰기 가능하며 char*로 변환해야 하는 문자열의 기본 주소를 가리킵니다.

2) 문자열을 const char*로 변환합니다.

   const char* s_r=&str[0];

위의 const char*(즉, s_r)는 읽을 수 있지만 쓸 수 없으며 문자열의 기본 주소를 가리킵니다.

은 특히 가 되는 것을 할 때 합니다.char*std::string, C 콜을 해, C 합니다.char*양쪽의 .++: C++std::stringC++에서 호출하는 C 라이브러리에서 직접 사용할 수 있습니다.

최신 C++ 사용방법std::string의 읽기 가능 C스타일의 /쓰기 가능 C스타일로char* 읽기 전용 " " " null-terminated " 입니다.const char*

「 」를 해야 ?std::string a까지char* ★★★const char*

매우 오래되고 높은 평가를 받고 있는 질문이지만, 제가 다루려는 정보는 아직 충분히 다루어지지 않았습니다.따라서 이것은 필요한 추가 사항입니다.특히 를 사용하여 기본 C-string을 사전에 할당해야 하는 부분에 대해서는,.resize()쓰기 가능한 버퍼로 사용하려는 경우 메서드를 사용합니다.

C++17 이후가 필요한 콜을 제외하고, 다음의 모든 사용법에는 C++11 이후가 필요합니다.

아래의 모든 샘플코드 및 기타 테스트를 수행하려면 eRCaGuy_hello_world repo에서 string_use_std_string_as_a_c_str_buffer.cpp 파일을 참조하십시오.

간단한 요약:

#include <string>
constexpr size_t BUFFER_SIZE = 100;
std::string str;
// IMPORTANT: pre-allocate the underlying buffer to guarantee what size it is
str.resize(BUFFER_SIZE); 

// -----------------------------------------------------------------------------
// Get read-writeable access to the underlying `char*` C-string at index i
// -----------------------------------------------------------------------------

char* c_str1 = &str[i]; // <=== my favorite!
char* c_str2 = str.data() + i;
char* c_str3 = &(*str.begin()) + i;

// NB: the C-strings above are NOT guaranteed to be null-terminated, so manually
// write in a null terminator at the index location where you want it if
// desired. Ex:
//
// 1. write a null terminator at some arbitrary position you choose (index 10
// here)
c_str1[10] = '\0'; 
// 2. write a null terminator at the last guaranteed valid position in the 
// underlying C-string/array of chars
c_str2[str.size() - i - 1] = '\0';

// -----------------------------------------------------------------------------
// Get read-only access to the underlying `const char*` C-string at index i
// -----------------------------------------------------------------------------
const char* const_c_str1 = &str[i];
const char* const_c_str2 = str.c_str() + i; // guaranteed to be null-terminated,
                                            // but not necessarily at the
                                            // position you desire; the
                                            // guaranteed null terminator will
                                            // be at index location 
                                            // `str.size()`

요약:.

급해서 필요한 경우:

  1. 가능한 쓰기 가능char*: 을 합니다.char* c_str1 = &str[i];를 클릭합니다.
    1. 우선 기본 버퍼 크기를 미리 할당해 두기만 하면 됩니다.str.resize(BUFFER_SIZE)필요한 경우 기본 버퍼가 필요에 따라 충분히 커지도록 하는 것만으로 충분합니다.
  2. 전용의 「 」const char*버퍼의 C합니다(「C」: 「C」).const char* const_c_str1 = &str[i];), 또는 const char* const_c_str1 = str.c_str() + i;.
#include <string>

constexpr size_t BUFFER_SIZE = 100;

std::string str;
// IMPORTANT: pre-allocate the underlying buffer to guarantee what size it is
str.resize(BUFFER_SIZE);  

// =============================================================================
// Now you can use the `std::string`'s underlying buffer directly as a C-string
// =============================================================================

// ---------------------------------------------------------
// A. As a read-writeable `char*` C-string
// ---------------------------------------------------------

// Technique 1 [best option if using C++11]: array indexing using `operator[]` 
// to obtain a char, followed by obtaining its address with `&`
// - Documentation: 
//   https://en.cppreference.com/w/cpp/string/basic_string/operator_at
char* c_str1 = &str[0];
char* c_str2 = &str[10];
char* c_str3 = &str[33];
// etc. 

// Technique 2 [best option if using C++17]: use the `.data()` method to obtain
// a `char*` directly.
// - Documentation: 
//   https://en.cppreference.com/w/cpp/string/basic_string/data
char* c_str11 = str.data();      // same as c_str1 above
char* c_str12 = str.data() + 10; // same as c_str2 above
char* c_str13 = str.data() + 33; // same as c_str3 above

// Technique 3 [fine in C++11 or later, but is awkward, so don't do this. It is
// for demonstration and learning purposes only]: use the `.begin()` method to
// obtain an iterator to the first char, and then use the iterator's 
// `operator*()` dereference method to obtain the iterator's `char`
// `value_type`, and then take the address of that to obtain a `char*`
// - Documentation:
//   - https://en.cppreference.com/w/cpp/string/basic_string/begin
//   - https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
char* c_str21 = &(*str.begin());      // same as c_str1 and c_str11 above
char* c_str22 = &(*str.begin()) + 10; // same as c_str2 and c_str12 above
char* c_str23 = &(*str.begin()) + 33; // same as c_str3 and c_str13 above


// ---------------------------------------------------------
// B. As a read-only, null-terminated `const char*` C-string
// ---------------------------------------------------------

// - Documentation:
//   https://en.cppreference.com/w/cpp/string/basic_string/c_str

const char* const_c_str1 = str.c_str();      // a const version of c_str1 above
const char* const_c_str2 = str.c_str() + 10; // a const version of c_str2 above
const char* const_c_str3 = str.c_str() + 33; // a const version of c_str3 above

, 이 경우에도 할 수 ..at(i) ★★★★★★★★★★★★★★★★★」.front() std::string방법론도 있지만, 제 예시로 충분하다고 생각하기 때문에 그 방법들에 대해서는 설명하지 않겠습니다.메뉴얼에 대해서는, 다음을 참조해 주세요.

  1. https://en.cppreference.com/w/cpp/string/basic_string/at
  2. https://en.cppreference.com/w/cpp/string/basic_string/front

세부사항:

위의 참고 사항도 참조하십시오. 그럼 이제 이 않겠습니다..at(i) ★★★★★★★★★★★★★★★★★」.front() std::string이미 제시한 몇 가지 기술만으로도 충분하다고 생각하기 때문입니다.

. 1. a를 사용하세요.std::string/읽기/읽기/char*

C++ 를 std::stringC스타일의 쓰기 가능 char*하여 버퍼를 해야 합니다..size()를 사용하여.resize() 를 사용하는 해 주세요..reserve() .capacity()충분하지 않습니다!cppreference.com 커뮤니티 Wiki 페이지의 올바른 상태는 다음과 같습니다.

ifpos > size()동작은 정의되어 있지 않습니다.

resize()method는 사이즈를 변경하는 것이 아니라reserve()만 )capacity().

예:

#include <cstring>  // `strcpy()`
#include <iostream>
#include <string>


constexpr size_t BUFFER_SIZE = 100;

std::string str;
str.resize(BUFFER_SIZE);  // pre-allocate the underlying buffer
// check the size
std::cout << "str.size() = " << str.size() << "\n";

다음의 예에서는, 다음의 C스트링이 있다고 가정합니다.

constexpr char cstr1[] = "abcde ";
constexpr char cstr2[] = "fghijk";

를 사전 큰 가 할당됩니다.resize() 기본 할 수 char*적어도 3가지 방법으로최소 3가지 방법으로:

  1. 기술 1 [C++11을 사용하는 경우 최선의 옵션]: 어레이 인덱싱을 사용하여 문자를 얻은에 주소를 가져옵니다. 예:
    char* c_str;
    c_str = &str[0];
    c_str = &str[5]; 
    // etc.
    
    // Write these 2 C-strings into a `std::string`'s underlying buffer
    strcpy(&str[0], cstr1);
    strcpy(&str[sizeof(cstr1) - 1], cstr2); // `- 1` to overwrite the first 
                                            // null terminator
    
    // print the string
    std::cout << str << "\n"; // output: `abcde fghijk`
    
    What if you have a pointer to a 만약 당신이 이 비디오에 대한 포인터를 가지고 있다면?std::string? ? If you have a ptr to a ptr이 있는 경우std::string, , it must be dereferenced first with 먼저 참조를 해제해야 합니다.*pstr before you can index into it as an array with the 를 사용하여 배열로 인덱싱할 수 있습니다.operator[] as ~하듯이&(*pstr)[0], 위의 구문은 조금 어색하게 된다.위의 구문은 조금 더 어색해집니다.다음으로 완전한 예를 제시하겠습니다.
    std::string str2;
    std::string* pstr = &str2;
    pstr->resize(BUFFER_SIZE);
    c_str = &(*pstr)[0]; // <=== dereference the ptr 1st before indexing into it
    // Or, to make the order of precedence 
    // (https://en.cppreference.com/w/cpp/language/operator_precedence) really
    // obvious, you can optionally add extra parenthesis like this:
    c_str = &((*pstr)[0]);
    
  2. 기법 2 [C++17을 사용하는 경우 최선의 옵션]: 를 직접 취득하는 방법을 사용합니다.예:
    char* c_str;
    c_str = str.data();
    c_str = str.data() + 5;
    // etc.
    
    // Write these 2 C-strings into the `std::string`'s underlying buffer
    strcpy(str.data(), cstr1);
    strcpy(str.data() + (sizeof(cstr1) - 1), cstr2); // `- 1` to overwrite the
                                                     // first null terminator
    
    // print the string
    std::cout << str << "\n"; // output: `abcde fghijk`
    
  3. 테크닉 3 [C++11 이후로는 괜찮지만 어색하니까 하지 마세요] 데모 및 학습 목적으로만 사용됩니다. 메서드를 사용하여 첫 번째 문자에 대한 반복자를 얻은 반복자의 참조 해제 메서드를 사용하여 반복자의value_type얻은 다음 해당 주소를 사용하여 얻습니다. 예:
    char* c_str;
    c_str = &(*str.begin());
    c_str = &(*str.begin()) + 5;
    // etc.
    
    // Write these 2 C-strings into the `std::string`'s underlying buffer
    strcpy(&(*str.begin()), cstr1);
    strcpy(&(*str.begin()) + (sizeof(cstr1) - 1), cstr2); // `- 1` to overwrite 
                                                          // the first null 
                                                          // terminator
    
    // print the string
    std::cout << str << "\n"; // output: `abcde fghijk`
    

해야 할 은, 할 때 입니다.str.resize(100)문자열에 하여 "100"을 설정합니다size()이 에 할당됩니다.100 것을 100에 대한 그 문자들 중char()--AKA: 기본값 초기화char(여기서 질문 참조), 바이너리 제로 늘 터미네이터입니다.'\0' 전화할 str.size()은 돌아올 것이다100그 끈이 단순히 가지고 있다고 해도"hello"95개의 늘 터미네이터 또는 0이 뒤따릅니다.문자열의 Null이 아닌 끝자 길이 또는 수를 가져오려면 C 함수에 의존해야 합니다.strlen() 이렇게요.

std::cout << strlen(str.c_str()) << "\n"; // prints `12` in the examples above

// instead of:
std::cout << str.size() << "\n"; // prints `100` in the examples above

2. Access a 2. a에 접속하다std::string as a read-only, null-terminated 읽기 전용으로 null-terminated로const char*

판독 가능한 null-terminated를 얻으려면const char*에에서std::string, 방법을 사용합니다.null-termination이 보증되는 C 스타일 문자열을 반환합니다.메서드는 null-termination이 보장되지 않으므로 동일한 것이 아닙니다.

예:

std::string str = "hello world";
printf("%s\n", str.c_str());

레퍼런스

  1. (스택 오버플로에 관한 질문)

    1. std:: 문자열을 const char* 또는 char*로 변환하는 방법: std:: 문자열을 const char* 또는 char*로 변환하는 방법
    2. std::string의 char* 버퍼에 직접 씁니다.std:: 문자열의 char* 버퍼에 직접 쓰기
    3. std:string의 버퍼를 얻을 수 있는 방법이 있습니까?std:string의 버퍼를 얻을 수 있는 방법이 있습니까?
  2. (내 콘텐츠)

    1. [내 테스트 코드] string__use_std_string_as_a_c_str_cr.cpp
    2. [My Q] 질문 하단에 있는 "인접적으로 관련된" 섹션을 참조하십시오.「uint8_t()」라고 하는 「char()」에의 호출은, C++의 함수로서 「int64_t()」라고 하는 정수 「T()」등입니다.
    3. *****+ [std:: string 내의 버퍼를 사전 변환하는 것에 대한 코멘트]:std:: 문자열의 char* 버퍼에 직접 쓰기
    4. *****+ [std:: 문자열에 스토리지를 사전 할당하는 방법에 대한 코멘트, char* 버퍼로 사용]std:string의 버퍼를 얻을 수 있는 방법이 있습니까?
  3. (cppreference.com 커뮤니티 Wiki에서)

    1. https://en.cppreference.com/w/cpp/string/basic_string:

      basic_string 요소는 연속적으로 저장됩니다.즉, basic_string s의 경우, &*(s.s.size) == &*s.s.size() + n 입니다.또, 마찬가지로 s[0]에 대한 포인터는 null 종단(C+char)의 첫 번째 요소에 대한 포인터가 예상되는 함수에 전달될 수 있습니다.

    2. https://en.cppreference.com/w/cpp/string/basic_string/operator_at

      지정된 위치 pos에 있는 문자에 대한 참조를 반환합니다.경계 검사는 수행되지 않습니다.pos > size()의 경우 동작은 정의되지 않습니다.

    3. https://en.cppreference.com/w/cpp/string/basic_string/resize

    4. https://en.cppreference.com/w/cpp/string/basic_string/reserve

    5. https://en.cppreference.com/w/cpp/string/basic_string/data

    6. https://en.cppreference.com/w/cpp/string/basic_string/c_str

    7. https://en.cppreference.com/w/cpp/string/basic_string/clear

이거 드셔보세요

std::string s(reinterpret_cast<const char *>(Data), Size);

언급URL : https://stackoverflow.com/questions/347949/how-to-convert-a-stdstring-to-const-char-or-char

반응형