본문 바로가기

문자열 std::string 본문

💘 C++/변수범위, 변수형

문자열 std::string

Hyonii 2022. 1. 23. 13:28

문자열 , std::string

글자나 문자들이 나열되어 있는 것들을 문자열(string)이라고 한다.

C++ 에서 문자열을 이용해 이름, 주소, 단어, 문장과 같은 텍스트를 출력한다.

문자열 리터럴(Ex. "Hello, world!")은 큰따옴표("") 사이에 배치되어 문자열로 식별된다.
문자열은 프로그램에서 흔히 사용되므로 대부분의 현대 프로그래밍 언어에는 문자열 자료형이 내장되어 있다.

C++은 표준 라이브러리의 일부로 문자열(string)이 포함되어 있다.

 

문자열에 마우스를 가져다 대면 const char[13]이라고 나오는데. [] 는 배열 array를 의미한다.

const char[13]이 나오니까 글자가 13개인가라고 생각할 수 있다.

하지만 글자는 12개이다.

문자열을 표현을 할 때에는 맨 뒤에 보이지 않는(끝난다는것을 표현하는) 글자가 하나 숨어있다.

std::string

C++의 문자열을 사용하려면 먼저 std::string에 대한 선언을 가져오기 위해  헤더 파일을 #include해야 한다.

이 작업이 완료되면 std::string 타입의 변수를 정의할 수 있다.

 

일반 변수와 마찬가지로, 다음과 같이 값을 초기화하거나 문자열 값을 할당할 수 있다.

 

my_hello를 초기화 하는 방법 세가지

문자열에는 숫자도 포함 할 수 있다.

 

대신 " " 을 안쓰면 문제가 생긴다. 정수를 문자열로 암시적 형변환 해주는 방법이 없기 때문

숫자를 문자열에 넣을 때는 " " 써서 넣어준다는 것을 기억하자.

대신 숫자로서 연산이 되지는 않는다.

문자열 입력 및 출력 (String input and output)

std::cout을 사용하여 문자열을 예상대로 출력 할 수 있다.

#include <iostream>
#include <string>

int main()
{
    std::string myName("Bing");
    std::cout << "My name is : " << myName;
    
    return 0;
}

//this prints
//My name is : Bing

그러나 std::cin과 함께 문자열을 사용하면 놀랄 일이 발생 할 수 있다.

 

name에 Bing Bing 을 넣고 엔터를 한번 눌렀더니 age 까지 BIng Bing 으로 출력된다.
이번에는 Bing 만 넣었더니 age도 입 력을 받는다.

중간에 빈칸이 있는 문자열을 넣으면 문제가 생길 수 있나 의심 해 볼 수 있다.

cin은 빈칸이있으면 하나 다 입력을 받았다고 판단한다.

연산자 >>를 사용하여 cin에서 문자열을 추출할 때, 

>>는 첫 번째 공백까지만 반환한다.

다른 모든 문자는 cin 내부에 남겨져 다음 추출을 기다린다.

 

그래서 string 을 입력을 받을 때는 get line 이라는 것을 쓸 수 있다.

std::getline()을 사용한 텍스트 입력(Use std::getline() to input text)

문자열 전체를 읽으려면 std::getline()함수를 사용하는 것이 좋다.

std::getline()은 두개의 매개변수가 있다.

첫번째 매개 변수는 std::cin 이고, 두번째 매개 변수는 std::string 변수다.

 

깔끔하게 입력이 되고 출력이 된다.

getline은 한줄을 enter 치는 순간 까지 쭉 입력을 받게해준다.

getline은 line 단위로 읽는데 빈칸을 읽는게 아니라 enter 칠 때 까지 읽는것.

Mixing std::cin and std::getline()

std::cin과 std::getline을 모두 사용하여 입력을 받으면 예기치 않은 동작이 발생 할 수 있다.

 

age를 int로 바꾸고 cin으로 입력을 받아보면 숫자 28뒤에 enter를 쳤더니 그게 다시 name 으로 들어갔다.

cin을 사용하여 숫자 값을 입력하면 cin은 숫자 값만 캡처할 뿐만 아니라 "\n"도 캡처한다.

그럼 cin은 실제로 "28\n" 문자열을 얻는다.

그런 다음 숫자 값 28를 추출해서 name 변수에 할당한다.

그러면 getline() 함수가 이름을 읽으러 갈 때 스트림에 "\n"이 남아있는 걸 보고 빈 문자열을 입력받았다고 생각하여 name 변수에 빈 문자열을 할당한다. 의도했던 결과가 아니다.

 

이것을 해결하는 방법으로는

buffer에서 첫번째 enter쳤던 내용들을 날려버리고 새롭게 입력을 받아달라고 하는 cin.ignore 라는 것이 있다. 

'\n'이 올 때까지 최대 32767개의 글자를 무시해라. 입력받은 것을 잊어버려라는 의미다.

입력할 때 길게 입력할 수 있기 때문에 2바이트 int로 표현가능한 가장 긴 signed value 값을 넣어준거다. 

 

이번엔 프로그램이 예상대로 작동한다.

std:cin으로 숫자 값을 읽은 후 스트림에서 "\n"을 제거하는 것이 좋다.

Magic Number 32767 ?

32767은 cin::ignore() 함수가 무시할 문자 수 이다.

이 숫자는 모든 플랫폼에서 2바이트 정수의 가장 큰 값이다.

기술적으로 무제한 입력을 무시하는 올바른 방법은 다음과 같다.

#include <limits>

//...

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
//Ignore unlimited characters until \n is removed

그러나 위 코드는 길 뿐만 아니라 헤더 파일까지 포함해야한다.

 

32767같은 매직넘버는 코드에 없는것이 좋다.

그렇다면 애를 교체 해 줄 수 있는 방법은 

#include <limits>를 해서

 

streamsize는 longlong 으로 되어있다.

이렇게해서 깔끔하게 magic number를 없앨 수는 있지만 <limits>를 include 해주어야 하고 타이핑 길이가 늘어난다.

 

방법은 두가지이다.

1. 그냥 32767 쓰기

2. 입력받는 코드를 나만의 라이브러리로 만들어서 줄여서 사용하는 방법.

 

나중에 GUI interface 만들 때는 입력기능을 제공해주는 라이브러리르 가져다 쓰게 된다.

굳이 이런 작업 안해도 됨

문자열 추가 (Appending strings)

연산자 + 을 사용해서 두 문자열을 연결하거나 연산자 +=를 사용해서 한 문자열을 다른 문자열에 추가 할 수 있다.

문자열 끼리 더하는 것을 append 라고 부른다.

 

이것은 더하기 연산자가 string class 안에 정의가 되어있어서 되는것이다.

이런식으로 기본데이터타입이 아닌 것도 마치 산술 연산 하는 것처럼 기능을 구현 할 수 있다.

문자열 길이 (String Length)

문자열의 길이를 알고 싶으면 length() 멤버 함수를 통해 문자열의 길이를 요청할 수 있다.

 

a의 길이를 측정해 볼 수 있다.

a.length() 에서 .을 찍은 것은 string class 안에 들어가 있는 함수를 호출하는 것 이다.

12가 나오는 것을 볼 수 있는데 문자열이 맨 앞과 맨 뒤에있는 따옴표를 제외하고 12 글자라는 의미이다.

 

마우를 가져다 대면은 const char[13]이 나온다

문자의 array 문자가 하나하나씩 메모리안에 나열되어 있는 형태로 볼 때는 13글자가 된다.

마지막에 문자열의 끝을 의미하는 null char가 하나 숨어있기 때문

 

'💘 C++ > 변수범위, 변수형' 카테고리의 다른 글

영역 제한 열거형 enum class  (0) 2022.01.23
열거형 enumerated types  (0) 2022.01.23
형변환 Type Conversion  (0) 2022.01.17
auto 키워드와 자료형 추론  (0) 2022.01.16
Using 문과 모호성 Ambiguity  (0) 2022.01.15
Comments