05.03 - 문자열, std::string
처음으로 작성한 C++ 프로그램은 다음과 같다.
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}
"Hello, world!"는 정확히 뭘까? "Hello, world!"는 문자열(string)이라고 불리는 연속적인 문자들의 모음이다. C++ 에서 문자열을 이용해 이름, 주소, 단어, 문장과 같은 텍스트를 출력한다. 문자열 리터럴(Ex. "Hello, world!")은 큰따옴표("") 사이에 배치되어 문자열로 식별된다.
문자열은 프로그램에서 흔히 사용되므로 대부분의 현대 프로그래밍 언어에는 문자열 자료형이 내장되어 있다. C++은 언어의 코어가 아닌 표준 라이브러리의 일부로 문자열(string)이 포함되어 있다.
std::string
C++의 문자열을 사용하려면 먼저 std::string
에 대한 선언을 가져오기 위해 <string>
헤더 파일을 #include
해야 한다. 이 작업이 완료되면 std::string
타입의 변수를 정의할 수 있다.
#include <string>
std::string myName;
일반 변수와 마찬가지로, 다음과 같이 값을 초기화하거나 문자열 값을 할당할 수 있다.
std::string myName("Alex"); // initialize myName with string literal "Alex"
myName = "John"; // assign variable myName the string literal "John"
문자열에는 숫자도 포함할 수 있다.
std::string myID("45");
문자열 형식에서 숫자는 숫자가 아닌 텍스트로 처리되므로 숫자처럼 조작할 수 없다. (Ex. 곱하기, 더하기 등) C++는 문자열 숫자를 정수 또는 부동 소수 점 값으로 자동 변환하지 않는다.
std::cout
을 사용하여 문자열을 예상대로 출력할 수 있다.
#include <string>
#include <iostream>
int main()
{
std::string myName("Alex");
std::cout << "My name is: " << myName;
return 0;
}
그러나 std:cin
과 함께 문자열을 사용하면 놀랄 일이 발생할 수 있다!
#include <string>
#include <iostream>
int main()
{
std::cout << "Enter your full name: ";
std::string name;
std::cin >> name;
std::cout << "Enter your age: ";
std::string age;
std::cin >> age;
std::cout << "Your name is " << name << " and your age is " << age;
}
Enter your full name: Boy Coding
Enter your age: 27
Your name is Boy and your age is Coding
무슨 일일까? 연산자 >>
를 사용하여 cin에서 문자열을 추출할 때, >>
는 첫 번째 공백까지만 반환한다. 다른 모든 문자는 cin 내부에 남겨져 다음 추출을 기달린다.
따라서 연산자 >>
를 사용하여 문자열을 변수 name
으로 추출할 때 "Boy"만 추출되어 std::cin 내에 "Coding"가 남겨져 다음 추출을 기다린다. >>
연산자를 다시 사용하여 변수 age
에 문자열을 추출하면 "27" 대신 "Coding"가 나타난다. 세 번째 추출을 수했한다면 "27"을 얻게 될 것이다.
std::getline()을 사용한 텍스트 입력 (Use std::getline() to input text)
문자열 전체를 읽으려면 std::getline()
함수를 사용하는 것이 좋다. std::getline()
은 두 개의 매개 변수가 있다. 첫 번째 매개 변수는 std::cin
이고, 두 번째 매개 변수는 std::string
변수다.
#include <string>
#include <iostream>
int main()
{
std::cout << "Enter your full name: ";
std::string name;
std::getline(std::cin, name);
std::cout << "Enter your age: ";
std::string age;
std::getline(std::cin, age);
std::cout << "Your name is " << name << " and your age is " << age;
}
Enter your full name: Boy Coding
Enter your age: 27
Your name is Boy Coding and your age is 27
Mixing std::cin and std::getline()
std::cin과 std::getline을 모두 사용하여 입력을 받으면 예기치 않은 동작이 발생할 수 있다.
#include <string>
#include <iostream>
int main()
{
std::cout << "Pick 1 or 2: ";
int choice { 0 };
std::cin >> choice;
std::cout << "Now enter your name: ";
std::string name;
std::getline(std::cin, name);
std::cout << "Hello, " << name << ", you picked " << choice << '\n';
return 0;
}
위 프로그램은 먼저 1이나 2를 입력하도록 요청하고 입력할 때까지 기다린다. 그러면 입력을 하고 난 뒤 이름을 입력해야 한다. 하지만 실제로는 이름을 입력할 때까지 기다리지 않는다! 대신 "Hello" 라인을 출력한 다음 종료한다. 무슨 일일까?
cin
을 사용하여 숫자 값을 입력하면 cin
은 숫자 값만 캡처할 뿐만 아니라 "\n"도 캡처한다. 그럼 cin
은 실제로 "2\n" 문자열을 얻는다. 그런 다음 숫자 값 2를 추출해서 choice
변수에 할당한다. 그러면 getline()
함수가 이름을 읽으러 갈 때 스트림에 "\n"이 남아있는 걸 보고 빈 문자열을 입력받았다고 생각하여 name
변수에 빈 문자열을 할당한다. 의도했던 결과가 아니다!
std:cin
으로 숫자 값을 읽은 후 스트림에서 "\n"을 제거하는 것이 좋다.
std::cin.ignore(32767, '\n');
choice
변수를 읽은 직후에 위 코드를 삽입하면, 관련 없는 개행이 스트림에서 제거되고 프로그램이 예상대로 작동한다!
int main()
{
std::cout << "Pick 1 or 2: ";
int choice { 0 };
std::cin >> choice;
std::cin.ignore(32767, '\n');
std::cout << "Now enter your name: ";
std::string name;
std::getline(std::cin, name);
std::cout << "Hello, " << name << ", you picked " << choice << '\n';
return 0;
}
std:cin
이 포함된 숫자 값을 읽는 경우, std:cin.ignore()
를 사용하여 관련 없는 새 라인을 제거하는 것이 좋다.
매직 넘버 32767은 무엇을 의미할까?
32767은 cin::ignore() 함수가 무시할 문자 수다. 이 숫자는 모든 플랫폼에서 2-byte 정수의 가장 큰 값이다.
기술적으로 무제한 입력을 무시하는 올바른 방법은 다음과 같다.
#include <limits>
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
그러나 위 코드는 길뿐만 아니라 헤더 파일까지 포함해야 한다. 대부분은 버퍼링 된 입력을 두 줄 이상 무시할 필요가 없으므로 32767을 사용하는 게 실용적이다.
문자열 추가 (Appending strings)
연산자 +
을 사용해서 두 문자열을 연결하거나 연산자 +=
를 사용해서 한 문자열을 다른 문자열에 추가할 수 있다.
#include <string>
#include <iostream>
int main()
{
std::string a("45");
std::string b("11");
std::cout << a + b << "\n";
a += " volts";
std::cout << a;
return 0;
}
연산자 +는 문자열 "45"와 "11"을 "4511"로 연결한다. 숫자처럼 더하지 않는다.
문자열 길이 (String length)
문자열의 길이를 알고 싶으면 length() 멤버 함수를 통해 문자열의 길이를 요청할 수 있다.
#include <string>
#include <iostream>
int main()
{
std::string myName("Alex");
std::cout << myName << " has " << myName.length() << " characters\n";
return 0;
}
문자열 길이를 알려면 length(myName)
대신 myName.length()
를 사용한다.
length() 함수는 지금까지 사용한 것처럼 일반적인 함수가 아니며, 멤버 함수라는 std::string에 속하는 특별한 유형의 함수다. 나중에 멤버 함수에 대해 자세히 설명할 예정이다.
번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/4-4b-an-introduction-to-stdstring/ 입니다.