C ++에서 문자열과 char [] 유형의 차이점 배열을 모두 사용하는 예제가

나는 약간의 C를 알고 있으며 이제 C ++을 살펴보고 있습니다. C 문자열을 처리하기 위해 char 배열에 익숙하지만 C ++ 코드를 살펴보면 문자열 유형과 char 배열을 모두 사용하는 예제가 있습니다.

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

int main () {
  string mystr;
  cout << "What's your name? ";
  getline (cin, mystr);
  cout << "Hello " << mystr << ".\n";
  cout << "What is your favorite team? ";
  getline (cin, mystr);
  cout << "I like " << mystr << " too!\n";
  return 0;
}

#include <iostream>
using namespace std;

int main () {
  char name[256], title[256];

  cout << "Enter your name: ";
  cin.getline (name,256);

  cout << "Enter your favourite movie: ";
  cin.getline (title,256);

  cout << name << "'s favourite movie is " << title;

  return 0;
}

( http://www.cplusplus.com의 두 가지 예 )

나는 이것이 널리 질문되고 대답 된 (분명히?) 질문이라고 생각하지만, 누군가 C ++에서 문자열을 처리하는 두 가지 방법 (성능, API 통합, 각 방식이 어떻게 다른지)을 말해 줄 수 있다면 좋을 것입니다 더 나은 …).

감사합니다.



답변

char 배열은 문자 배열입니다.

  • 스택에 할당되면 (예와 같이) 항상 예를 ​​들어 점유합니다. 텍스트 길이에 관계없이 256 바이트
  • 힙에 할당 된 경우 (malloc () 또는 new char [] 사용) 이후에 메모리를 해제해야하며 항상 힙 할당 오버 헤드가 발생합니다.
  • 256 자 이상의 텍스트를 배열에 복사하면 충돌이 발생하고 어설 션 메시지가 생성되거나 프로그램의 다른 곳에서 설명 할 수없는 (미스) 동작이 발생할 수 있습니다.
  • 텍스트의 길이를 결정하려면 문자를 기준으로 \ 0 문자의 배열을 스캔해야합니다.

문자열은 char 배열을 포함하는 클래스이지만 자동으로 관리합니다. 대부분의 문자열 구현에는 16 문자의 내장 배열이 있으므로 짧은 문자열은 힙을 조각화하지 않으며 더 긴 문자열에는 힙을 사용합니다.

다음과 같이 문자열의 char 배열에 액세스 할 수 있습니다.

std::string myString = "Hello World";
const char *myStringChars = myString.c_str();

C ++ 문자열에는 \ 0 문자가 포함될 수 있으며, 계산없이 길이를 알 수 있고, 짧은 텍스트의 경우 힙 할당 문자 배열보다 빠르며 버퍼 오버런으로부터 보호 할 수 있습니다. 또한 읽기 쉽고 사용하기 쉽습니다.


그러나 C ++ 문자열은 DLL 경계를 넘어서서 사용하기에 (매우) 적합하지 않습니다. 왜냐하면 문자열 함수가 다르게 동작 할 위험이 없도록, DLL 함수를 사용하는 사용자는 정확히 동일한 컴파일러 및 C ++ 런타임 구현을 사용해야합니다.

일반적으로 문자열 클래스는 호출 힙에서 힙 메모리를 해제하므로 공유 (.dll 또는 .so) 버전의 런타임을 사용하는 경우에만 메모리를 다시 확보 할 수 있습니다.

간단히 말해서 : 모든 내부 함수와 메소드에서 C ++ 문자열을 사용하십시오. .dll 또는 .so를 작성하는 경우 공용 (dll / so-exposed) 함수에서 C 문자열을 사용하십시오.


답변

Arkaitz는 string관리 유형입니다. 이것이 당신에게 의미 하는 것은 문자열의 길이에 대해 걱정할 필요가 없으며 문자열의 메모리를 비우거나 다시 할당하는 것에 대해 걱정할 필요가 없다는 것입니다.

반면에 char[]위 의 표기법은 문자 버퍼를 정확히 256 자로 제한했습니다. 해당 버퍼에 256 자 이상을 쓰려고하면 프로그램이 소유 한 다른 메모리를 덮어 씁니다. 최악의 경우, 소유하지 않은 메모리를 덮어 쓰려고 시도하고 OS가 그 자리에서 프로그램을 종료시킵니다.

결론? 문자열은 프로그래머에게 훨씬 친숙하고, char []는 컴퓨터에 훨씬 효율적입니다.


답변

문자열 유형은 문자열에 대해 완전히 관리되는 클래스 인 반면, char []는 여전히 C에있는 문자열입니다 (문자열을 나타내는 바이트 배열).

API 및 표준 라이브러리 측면에서 모든 것은 char []가 아닌 문자열 측면에서 구현되지만 char []를받는 libc에는 여전히 많은 함수가 있으므로 char []를 제외하고는 함수를 사용해야 할 수도 있습니다. 항상 std :: string을 사용하십시오.

물론 효율성 측면에서 관리되지 않는 메모리의 원시 버퍼는 대부분 많은 경우에 거의 항상 빠를 것이지만 문자열 비교를 고려하십시오. 문자별로 비교해야합니다.


답변

나는 개인적으로 오래된 코드와의 호환성을 제외하고 char * 또는 char []를 사용하려는 이유를 알지 못합니다. std :: string은 c-string을 사용하는 것보다 느리지 않습니다. 단, 재배치가 처리됩니다. 만들 때 크기를 설정할 수 있으므로 원하는 경우 다시 할당하지 않아도됩니다. 인덱싱 연산자 ([])는 일정한 시간 액세스를 제공합니다 (그리고 모든 의미에서 c-string 인덱서를 사용하는 것과 똑같은 의미입니다). at 메소드를 사용하면 검사하지 않은 한 안전 검사를받을 수 있으며 c 문자열로 얻을 수없는 것입니다. 컴파일러는 릴리스 모드에서 인덱서 사용을 대부분 최적화합니다. c- 문자열로 엉망이되기 쉽습니다. delete vs delete [], 예외 안전, c- 문자열 재 할당 방법 등.

그리고 COW 문자열, MT를위한 비 COW와 같은 고급 개념을 다루어야 할 때는 std :: string이 필요합니다.

참조를 사용하고 가능한 한 참조를 const 참조하는 한 복사가 걱정된다면 복사로 인한 오버 헤드가 없으며 c-string으로 수행하는 것과 동일합니다.


답변

문자열에는 도우미 기능이 있으며 문자 배열을 자동으로 관리합니다. 문자열을 연결할 수 있으며, char 배열의 경우 새 배열에 복사해야하며 런타임에 문자열의 길이를 변경할 수 있습니다. char 배열은 문자열보다 관리하기 어렵고 특정 함수는 문자열을 입력으로 만 받아 들일 수 있으므로 배열을 문자열로 변환해야합니다. 배열을 사용하지 않아도되도록 문자열을 사용하는 것이 좋습니다. 배열이 객관적으로 좋으면 문자열이 없을 것입니다.


답변

(char *)를 string.begin ()으로 생각하십시오. 근본적인 차이점은 (char *)는 반복자이고 std :: string은 컨테이너라는 것입니다. 기본 문자열을 고수하면 (char *)가 std :: string :: iterator의 기능을 제공합니다. 반복자의 이점과 C와의 호환성을 원할 때 (char *)를 사용할 수 있지만 예외는 예외입니다. 항상 그렇듯이 반복자 무효화에주의하십시오. 사람들이 (char *) 안전하지 않다고 말할 때 이것이 의미하는 바입니다. 다른 C ++ 반복자만큼 안전합니다.


답변

차이점 중 하나는 Null 종료 (\ 0)입니다.

C 및 C ++에서 char * 또는 char []는 매개 변수로 단일 char에 대한 포인터를 가져 와서 0 메모리 값에 도달 할 때까지 메모리를 따라 추적합니다 (종종 널 종료 자라고 함).

C ++ 문자열에는 \ 0 문자가 포함될 수 있으며, 길이를 세지 않고 알 수 있습니다.

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

using namespace std;

void NullTerminatedString(string str){
   int NUll_term = 3;
   str[NUll_term] = '\0';       // specific character is kept as NULL in string
   cout << str << endl <<endl <<endl;
}

void NullTerminatedChar(char *str){
   int NUll_term = 3;
   str[NUll_term] = 0;     // from specific, all the character are removed 
   cout << str << endl;
}

int main(){
  string str = "Feels Happy";
  printf("string = %s\n", str.c_str());
  printf("strlen = %d\n", strlen(str.c_str()));
  printf("size = %d\n", str.size());
  printf("sizeof = %d\n", sizeof(str)); // sizeof std::string class  and compiler dependent
  NullTerminatedString(str);


  char str1[12] = "Feels Happy";
  printf("char[] = %s\n", str1);
  printf("strlen = %d\n", strlen(str1));
  printf("sizeof = %d\n", sizeof(str1));    // sizeof char array
  NullTerminatedChar(str1);
  return 0;
}

산출:

strlen = 11
size = 11
sizeof = 32
Fee s Happy


strlen = 11
sizeof = 12
Fee