C++ 문자열 처리

C++ string handling

C++ 프로그래밍 언어는 문자열 처리를 지원하며, 대부분 표준 라이브러리에 구현됩니다.언어 표준은 몇 가지 문자열 유형을 지정하며, 일부는 C에서 상속되며 일부는 클래스 및 RAII와 같은 언어의 기능을 사용하도록 설계되었습니다.이 중에서 가장 많이 사용되는 것은std:: 문자열.

C++의 초기 버전은 "저수준"의 C 문자열 처리 기능 및 표기법만을 가지고 있었기 때문에 스트링 처리 클래스를 위해 여러 호환되지 않는 설계가 수년간 설계되어 왔으며 여전히 사용되고 있습니다.std::string및 C++ 프로그래머는 단일 응용 프로그램에서 여러 규칙을 처리해야 할 수 있습니다.

역사

std::string 타입은 1998년 이후 표준 C++의 주요 문자열 데이터 타입이지만 항상 C++의 일부였던 것은 아닙니다.C++는 첫 번째 요소에 대한 포인터로 처리되는 늘 종단 문자열과 이러한 문자열을 조작하는 함수 라이브러리를 사용하는 규칙을 C에서 계승했습니다.최신 표준 C++에서는 "hello"와 같은 문자열 리터럴은 NUL로 종단된 문자 [1]배열을 나타냅니다.

C++ 클래스를 사용하여 문자열 유형을 구현하면 메모리 관리를 자동화하고 Out-Out-Bounds [2]액세스 위험을 줄일 수 있습니다.또한 문자열 비교 및 연결을 위한 보다 직관적인 구문을 사용할 수 있습니다.그러므로, 그러한 클래스를 만드는 것은 매우 유혹적이었다.수년간 C++ 애플리케이션, 라이브러리 및 프레임워크 개발자는 AT&T의 Standard Components 라이브러리(최초의 구현, 1983년)[3]나 Microsoft [4]MFCCString 타입 등 호환성이 없는 독자적인 문자열 표현을 작성했습니다.std:: string 표준화된 문자열에 비해 레거시 어플리케이션에는 이러한 커스텀 문자열 타입이 여전히 포함되어 있으며 라이브러리는 C-스타일 문자열을 예상할 수 있기 때문에 C++ 프로그램에서[1] 여러 문자열 타입을 사용하는 것을 피할 수 없게 [4]되어 프로그래머가 프로젝트를 시작하기 전에 원하는 문자열 표현을 결정할 필요가 있습니다.

1991년 C++의 역사에 대한 회고전에서, 그것의 발명가 Bjarne Strostrup은 C++ 1.0에 표준 문자열 타입(및 일부 표준 타입)이 없는 것을 그가 개발하면서 저지른 최악의 실수라고 말했다. "이것들의 부재는 모두가 바퀴를 재발명하고 가장 기본적인 등급에서 불필요한 다양성을 야기시켰다."[3]

구현 문제

각 벤더의 문자열 유형은 구현 전략과 성능 특성이 다릅니다.특히 일부 문자열 유형은 다음과 같은 작업을 수행하는 쓰기 시 복사-on-Write 전략을 사용합니다.

스트링 a = "안녕하세요!"; 스트링 b = a; // 생성자 복사 

는 실제로 a의 내용b에 복사하지 않습니다.대신 두 문자열이 내용을 공유하고 콘텐츠 참조 카운트가 증가합니다.어느 하나의 문자열에 문자를 추가하는 등의 변환 조작에 의해 문자열의 내용이 달라질 때까지 실제 복사는 연기됩니다.Copy-on-Write는 문자열을 사용하여 코드의 성능을 크게 변경할 수 있습니다(일부 작업은 훨씬 빠르고 일부는 훨씬 느립니다).std::string은 더 이상 사용하지 않지만 많은 대체 문자열 라이브러리는 여전히 Copy-on-Write 문자열을 구현합니다.

일부 문자열 구현에서는 바이트 대신 16비트 또는 32비트 코드 포인트를 저장합니다.이것은 Unicode [5]텍스트의 처리를 용이하게 하기 위한 것입니다.단, std::string 또는 바이트 배열에서 이러한 유형으로 변환하는 것은 "locale"에 의존하며 예외를 [6]발생시킬 수 있습니다.16비트 코드 유닛의 처리상의 이점은 가변폭 UTF-16 인코딩이 도입되었을 때 사라졌습니다(단, Windows 등의 16비트 API와 통신할 필요가 있는 경우에도 이점이 있습니다).QTQString[5]그 예입니다.

서드파티 문자열 구현은 하위 문자열을 추출 또는 비교하거나 텍스트 검색을 수행하기 위한 구문에서도 상당한 차이를 보였습니다.

표준 문자열 유형

std::string 클래스는 C++98 이후의 텍스트 문자열의 표준 표현입니다.클래스는 비교, 연결, 검색 및 치환과 같은 일반적인 문자열 연산과 하위 문자열을 얻기 위한 함수를 제공합니다.std:: 문자열은 C 스타일 문자열에서 구성할 수 있으며,[7] C 스타일 문자열도 C 스타일 문자열에서 얻을 수 있습니다.

문자열을 구성하는 개별 단위는 각각 최소 8비트(거의 항상)의 char 유형입니다.현대의 사용법에서는, 이러한 문자는 「문자」가 아니고, UTF-8등멀티 바이트 문자 인코딩의 일부입니다.

Copy-on-Write 전략은 초기 C++ Standard에서 std::string에 대해 의도적으로 허용되었습니다.이는 Copy-on-Write 전략이 유용한 최적화로 간주되어 거의 모든 [7]구현에서 사용되었기 때문입니다.단, 오류가 있었습니다.특히 연산자[]는 포트 C의 in-place 문자열 조작을 용이하게 하기 위해 부정수 참조를 반환했습니다(이러한 코드는 문자당 1바이트로 가정되는 경우가 많으므로 이는 좋은 생각이 아닐 수 있습니다).이것에 의해, 거의 항상 스트링의 검사에만 사용되고 [8][9]변경에는 사용되지 않지만, 카피를 작성할 필요가 있는 것을 나타내는 다음의 코드가 가능하게 되었습니다.

  표준::스트링 원래의("아아아아아아아아");   표준::스트링 string_copy = 원래의; // 복사하기   * 포인터 = &string_copy[3]; // 연산자 []가 "trick" 클래스를 반환하려고 했지만 이것이 복잡해졌습니다.   arbitary_code_여기서(); // 최적화로는 해결할 수 없습니다.   *포인터 = 'b'; // 연산자 []가 복사하지 않으면 원본이 예기치 않게 변경됩니다. 

이로 인해 일부 구현은[which?] Copy-on-Write를 포기했습니다.또한 참조 카운트를 조사하거나 변경하는 데 필요한 잠금으로 인한 멀티 스레드 애플리케이션의 오버헤드가 최신 프로세서에서[10] 작은 문자열을 복사하는 오버헤드(특히 포인터 크기보다 작은 문자열의 경우)보다 크다는 것이 밝혀졌습니다.C++[8]11에서는 최적화가 최종적으로 허가되지 않았습니다.그 결과 std:: 문자열을 인수로서 함수 viz에 전달해도 됩니다.

무효 인쇄물(표준::스트링 s) { 표준::외치다 << > s; } 

는 새로 할당된 메모리에 문자열의 완전한 복사를 수행해야 합니다.이러한 복사를 피하기 위한 일반적인 관용구는 const reference로 전달하는 것입니다.

무효 인쇄물(컨스턴트 표준::스트링& s) { 표준::외치다 << > s; } 

C++17에서 읽기 전용 데이터에 대한 포인터 및 길이에 불과한 새로운 string_view[11] 클래스가 추가되었습니다.이 클래스는 위의 예보다 훨씬 빠르게 인수를 전달합니다.

무효 인쇄물(표준::string_view s) { 표준::외치다 << > s; } ...   표준::스트링 x = ...;   인쇄물(x); // x.data()를 복사하지 않음   인쇄물("이것은 리터럴 문자열입니다."); // 또한 문자를 복사하지 않습니다! ... 

사용 예

#실패하다 <iostream> #실패하다 <iomanip> #실패하다 <문자열>  인트 주된() {     표준::스트링 후우 = "실패";     표준::스트링 막대기 = "실패";     한다면 (후우 != 막대기) 표준::외치다 << > "줄이 달라요!\n";     표준::외치다 << > "foo = " << > 표준::따옴표(후우)               << > " bar = " 동안 << > 표준::따옴표(막대기); } 

관련 클래스

std::stringstd::basic_string 템플릿클래스[12]특정 인스턴스화의 typedef입니다.이 정의는 <string> 헤더에 있습니다.

사용. 스트링 = 표준::basic_string< >>; 

따라서 문자열은 char 유형의 요소를 가진 문자열에 basic_string 기능을 제공합니다.wchar t로 구성되는 유사한 클래스 std::wstring이 있으며 Windows에서는 UTF-16 텍스트를 저장하고 대부분의 Unix 유사 플랫폼에서는 UTF-32를 저장할 때 가장 많이 사용됩니다.단, C++ 규격에서는 이러한 타입에 Unicode 코드 포인트 또는 코드 유닛으로 해석되지 않으며 wchar_t[13]문자보다 많은 비트를 보유하는 것도 보증되지 않습니다.wchar_t 속성에 기인하는 비호환성의 일부를 해결하기 위해 C++11에서는 std:u16stringstd:u32string(새로운 타입 char16_tchar32_t로 구성됨)의 2개의 새로운 클래스가 추가되었습니다.이 클래스는 모든 [14]플랫폼의 코드 단위당 비트 수입니다.또한 C++11은 16비트 및 32비트의 새로운 문자열 리터럴과 유니코드 코드 포인트를 늘 종단(C-스타일)[15] 문자열에 추가하기 위한 구문을 추가했습니다.

basic_stringchar_traits 구조체가 수반되는 모든 유형에 대해 특화 가능함을 보증합니다.C++11 에서는, char, wchar_t, char16_t, char32_t 의 각 사양만을 [16]실장할 필요가 있습니다.

basic_string표준 라이브러리 컨테이너이기도 합니다.따라서 표준 라이브러리 알고리즘은 문자열의 코드 유닛에 적용할 수 있습니다.

크리틱

std::string의 설계는 C++98 클래스의 103개의 멤버 함수 중 71개가 구현 [17]효율의 손실 없이 분리될 수 있다고 생각하는 Herb Sutter에 의해 모노리식 설계의 예로 제시되었습니다.

레퍼런스

  1. ^ a b Seacord, Robert C. (2013). Secure Coding in C and C++. Addison-Wesley. ISBN 9780132981972.
  2. ^ Oualline, Steve (2003). Practical C++ Programming. O'Reilly.
  3. ^ a b Stroustrup, Bjarne (1993). A History of C++: 1979–1991 (PDF). Proc. ACM History of Programming Languages Conf.
  4. ^ a b Solter, Nicholas A.; Kleper, Scott J. (2005). Professional C++. John Wiley & Sons. p. 23. ISBN 9780764589492.
  5. ^ a b Blanchette, Jasmin; Summerfield, Mark (2008). C++ GUI Programming with Qt4. Pearson Education. ISBN 9780132703000.
  6. ^ "wstring_convert Class". docs.microsoft.com. 3 August 2021. Retrieved 26 December 2021.
  7. ^ a b Meyers, Scott (2012), Effective STL, Addison-Wesley, pp. 64–65, ISBN 9780132979184
  8. ^ a b Meredith, Alisdair; Boehm, Hans; Crowl, Lawrence; Dimov, Peter (2008). "Concurrency Modifications to Basic String". ISO/IEC JTC 1/SC 22/WG 21. Retrieved 19 November 2015.
  9. ^ "21334 – Lack of Posix compliant thread safety in STD::basic_string".
  10. ^ Sutter, Herb (1999). "Optimizations That Aren't (In a Multithreaded World)". C/C++ Users Journal. 17 (6).
  11. ^ "std::basic_string_view – cppreference.com". en.cppreference.com. Retrieved 23 June 2016.
  12. ^ "C++ reference for basic_string". Cppreference.com. Retrieved 11 January 2011.
  13. ^ Gillam, Richard (2003). Unicode Demystified: A Practical Programmer's Guide to the Encoding Standard. Addison-Wesley Professional. p. 714. ISBN 9780201700527.
  14. ^ "C++11 Paper N3336". Open Standards. Programming Language C++, Library Working Group. 13 January 2012. Retrieved 2 November 2013.
  15. ^ Stroustrup, Bjarne (2013). The C++ Programming Language. Addison Wesley. p. 179. Archived from the original on 25 November 2015. Retrieved 24 November 2015.
  16. ^ "char_traits – C++ Reference". Retrieved 1 August 2015.
  17. ^ Sutter, Herb. "Monoliths "Unstrung"". gotw.ca. Retrieved 23 November 2015.