C++ - string

mohadang·2022년 9월 17일
0

C++

목록 보기
4/48
post-thumbnail
post-custom-banner

c 스타일의 문자열 문제점

char line[256];
cin.getline(line, 256);

/*
1. 아무것도 읽지 못했을 때
2. 한 줄에 문자가 245자 이상일 때
	- fail bit 설정 된다. 남은 문자열들은 스트림에 존재

* 256은 Magic Number
	const int LINE_LENGTH = 256;
*/

std::string

  • std::string 클래스를 이용한 문자열은 길이가 증가할 수 있음
  • 문자열 연산을 위한 다양한 연산자를 제공
string str = str1 + str2;

if(firstName1 > firstName2); // 사전순 비교

if(firstName1 == firstName2);

//C++에선는 문자열 연산이 직관적이고 길이 체크도 알아서 하기 때문에 편리
  • 다양한 함수 제공
    • str.size(), str.length() : 문자열 길이 반환('length는 잘 사용하지 않음')
  • c_str() :
    • 옛날 방식의 문자열 반환
    • 해당 string이 가지고 있는 문자 배열의 시작 주소를 가리키는 포인터를 반환
    • const char*
string line;
cin >> line;
const char* cLine = lilne.c_str();

/*
C 함수와 호환되기 위해 필요할 때 가 있다.
메모리 문제는 없다
*/  
  • Index
    • 사실은 함수를 호출하는 것이다
char letter = str[0];
str[1] = 'P'

/*
반환값에 값을 대입??? 반환값은 복사된 값인데 제대로 값이 써질까??
YES!!, 그냥 반환값이 아니라 '참조 반환값'이라서 가능, '참조'를 이렇게도 유용하게 사용 할 수 있음
*/      
  • at
char letter = str.at(0);
str.at(1) = 'P'
  • 한줄 읽기
//\n 문자를 만날 때 까지 cin에서 문자들을 꺼내서 mailHeader에 저장
string str;
getline(cin, str);
	
//위와 동작은 같지만 \n 대신 @를 만날때 까지
getline(cin, str, '@')

//eof나 구분문자 \n (사용자가 지정할 수 있다 : @) 만날때 까지 읽어 들인다.

sstream(String stream)

  • std::istringsream
    - cin과 비슷: 키보드 대신 string으로부터 읽어옴
    - sscanf()와 비슷

  • std::ostringstream
    - cout과 비슷: 키보드 대신 string에 출력함
    - sprintf()와 비슷

  • EX

#include <sstream>
std::ostringstream oss;
oss << "abc" << 123 << std::endl;
oss << "두번째 줄" <<  now() << std::endl;
/*
...
std::string res = oss.str();
- String Builder 같다.
*/
  • EX
istringstream s("hello 3.13 123");
string name;
float f;
int i;
s>>name>>f>>i;
cout<<f<<name<<i<<endl;

cout, cin 도 스트림이지만 자주 사용하지 않음

  • C 헤더를 써도 될까???
    - Yes !!!
    - '성능상 문제로 C 함수 자주 사용'

  • C
    - string.h
    - stdio.h
    - ctype.h

  • C++
    - cstring
    - cstdio
    - cctype
    - 앞에 C만 붙이면 됨

string의 메모리 복사, 메모리 할당

(1)
- code
  string line;

- memory
  포인터(ptr) -> [0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
  길이(size)     [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]
  용량(15)       [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]
                 [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]
  - 내부적으로 처음 string이 생성될 때 16byte 정도는 미리 할당함(capacity), 따라서 15개의 문자는 저장가능한 상태임

(2)
- code
  line = "POPE";

- memory
  포인터(ptr) -> [P][O][P][E][0][0][0][0][0][0][0][0][0][0][0][0]
  길이(4)        [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]
  용량(15)       [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]
                 [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]

  - POPE라는 문자열 어디선가 목사하고 끝에 NULL 추가

(3)
- code
  line += "C++ is awesome, isn't?";

- memory
포인터(ptr)-    [P][O][P][E][0][0][0][0][0][0][0][0][0][0][0][0]
길이(26)    |   [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]
용량(31)    |   [X][X][X][X][X][X][X][X][X][X][X][X][X][X][X][X]
            -->	[X][X][X][P][O][P][E][C][+][+][ ][i][s]...

- "POPE"와 "C++ is..." 라는 문자열 합한 길이는 26, 용량은 31
- 32바이트 만큼 메모리 할당
- ptr이 32바이트 주소 공간을 새로 가리키게 함
- 32바이트 임의의 공간에 "POPE"라는 문자열 저장하고 기존 포인터가 가리키고 있던 문자열은 삭제
- "C++ is..." 문자열을 POPE 뒤에 붙여넣음
  • 이 과정에서 "메모리 복사"와 "메모리 할당" 리소스 발생
    • "힙 메모리 할당은 느림"
      • 스택보다 느림
      • 힙은 OS 전체에서 사용할 수 있는 메모리 찾아야함
    • 메모리 단편화 문제
      • 임베디드에서 자주 발생
    • 내부 버퍼의 증가는 멀티 쓰레드 환경에서 안전하지 않을 수도
    • C++를 쓰는 업계가 어디인가??? 성능이 중요한 곳이다. 그래서 여전히 sprintf와 함께 char[]를 매우 많이 사용
    • c_str()
      • string의 포인터를 반환함
      • string이 가지고 있는 메모리 내용을 바꾸면 길이나 용량등 메타데이터가 깨지기 때문에 const char*를 반환함
profile
mohadang
post-custom-banner

0개의 댓글