1) C++ 문자열
문자열이란 메모리에 저장된 일련의 연속된 문자들의 집합을 의미한다.
C++에서는 C언어 스타일의 문자열과 string 클래스를 이용한 문자열. 이렇게 2가지 방법으로 문자열을 만들 수 있다.
C언어 스타일의 문자열
C++에서는 큰따옴표를 사용해 표현되는 문자열을 문자열 상수라고 한다.
상수라고 표현하는 이유는 해당 문자열이 이름을 갖고 있지 않고, 문자열의 내용도 변경할 수 없기 때문이다.
널(NULL) 문자
C++에서 문자형 배열로 선언된 문자열 변수는 끝을 프로그램에 직접 알려주어야 한다.
그래야 프로그램은 실제 문자열에 속한 값과 그 외의 쓰레기값을 구분할 수 있기 때문이다.
문자열에 속한 데이터가 끝나면, 문자열의 끝을 의미하는 문자를 하나 더 삽입해 주면 되는데 이러한 문자를 널(NULL) 문자라고 하는 것이다. ‘\0’으로 표기할 수 있으며 아스키코드 값은 0이다.
💡 문자열을 저장하기 위한 문자형 배열을 선언할 때는 반드시 널 문자를 포함해서 생각해야 한다.
문자열 입력
문자열을 입력받기 위해서는 문자열이 저장될 문자형 배열을 미리 만들어두어야 한다.
const int SIZE = 20;
char address[SIZE];
char name[SIZE];
cout << "자신의 이름을 적어주세요 : ";
cin >> name;
cout << "자신이 살고 있는 도시를 적어주세요 : ";
cin >> address;
cout << address << "에 살고 있는 " << name << "님~ 감사합니다!";
자신의 이름을 적어주세요 : 홍길동
자신이 살고 있는 도시를 적어주세요 : 서울
서울에 살고 있는 홍길동님~ 감사합니다!
자신의 이름을 적어주세요 : 이 순신
자신이 살고 있는 도시를 적어주세요 : 순신에 살고 있는 이님~ 감사합니다!
위의 예제 코드에는 문제가 있다.
- 이름에 띄어쓰기가 들어가면 도시명을 입력할 수 없게 된다.
- 20 바이트 이상의 이름이나 도시명을 입력하면 강제 종료된다.
문자열 입력: get() 메소드
C++에서 cin 객체는 띄어쓰기를 포함한 탭 문자를 모두 문자열의 끝으로 인식한다.
따라서 띄어쓰기가 사용된 문자열을 전부 입력받기 위해서는 get() 메소드를 사용하면 된다.
const int SIZE = 20;
char address[SIZE];
char name[SIZE];
cout << "자신의 이름을 적어주세요 : ";
cin.get(name, SIZE).get();
cout << "자신이 살고 있는 도시를 적어주세요 : ";
cin.get(address, SIZE).get();
cout << address << "에 살고 있는 " << name << "님~ 감사합니다!";
자신의 이름을 적어주세요 : 이 순신
자신이 살고 있는 도시를 적어주세요 : 부산
부산에 살고 있는 이 순신님~ 감사합니다!
get() 메소드를 통해 띄어쓰기가 포함된 이름이나 도시명을 전부 받을 수 있게 되었다.
get() 함수는 특정 문자나 개행 문자에 도달할 때까지 읽기를 수행하고 디폴트로 공백 문장을 무시한다.
그러나!
아직도 20바이트 이상의 문자를 입력하는 경우 전체 값을 입력받지 못한다.
이 문제는 cin 객체의 ignore() 메소드로 해결할 수 있다.
문자열 입력: ignore() 메소드
const int SIZE = 20;
char address[SIZE];
char name[SIZE];
cout << "자신의 이름을 적어주세요 : ";
cin.get(name, SIZE).ignore(SIZE, '\\n');
cout << "자신이 살고 있는 도시를 적어주세요 : ";
cin.get(address, SIZE).ignore(SIZE, '\\n');
cout << address << "에 살고 있는 " << name << "님~ 감사합니다!";
자신의 이름을 적어주세요 : abcdefghijklmnopqrstuvwxyz
자신이 살고 있는 도시를 적어주세요 : ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRS에 살고 있는 abcdefghijklmnopqrs님~ 감사합니다!
이제 정상적으로 모든 값을 입력받을 수 있게 된 것이다.
cin.get(name, SIZE).get();
cin.get(name, SIZE).ignore(SIZE, '\\n');
C++의 ignore() 함수는 스트림에서 문자를 무시하거나 특정 문자까지 무시하는 데 사용되며, ignore() 함수는 주로 입력 버퍼에서 개행 문자나 특정 문자를 제거하거나 무시할 때 사용된다.
아래의 코드는 10개의 문자를 무시하는 경우이고,
cin.ignore(10); // 입력 버퍼에서 10개의 문자를 무시
아래의 코드는 특정 문자를 무시하는 경우이다.
cin.ignore(100, '\\n'); // 입력 버퍼에서 최대 99개의 문자를 무시하거나 개행 문자('\\n')를 만날 때까지 무시
문자열 입력: string 클래스
std::string은 C++ 표준 라이브러리에서 제공하는 문자열을 다루기 위한 클래스이다. 문자열을 효과적으로 다루기 위한 여러 기능을 제공하는데 특히 가변적인 길이의 문자열을 다룰 때 매우 유용하다.
위에서는 입력받을 문자열에 맞춰 미리 문자열의 길이를 정해두었지만, string 클래스를 이용하면 문자열의 길이 따위는 신경 쓰지 않아도 된다.
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string address, name;
cout << "자신의 이름을 적어주세요 : ";
getline(cin, name);
cout << "자신이 살고 있는 도시를 적어주세요 : ";
getline(cin, address);
cout << address << "에 살고 있는 " << name << "님~ 감사합니다!";
return 0;
}
자신의 이름을 적어주세요 : 가나다라마바사아자차카타파하
자신이 살고 있는 도시를 적어주세요 : ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ에 살고 있는 가나다라마바사아자차카타파하님~ 감사합니다!
문자열의 띄어쓰기 문제나 문자열의 길이와 상관없이 모든 문자열을 정확하게 입력받는 것을 알 수 있다.
2) string 클래스
string 클래스는 앞서 사용했듯 문자형 배열을 편하게 사용할 수 있도록 해주고 문자열을 하나의 타입처럼 표현할 수 있게 해 준다. C++에서 string 클래스를 사용하기 위해서는 우선 string 헤더 파일을 포함해야 하며 string 클래스는 std 네임스페이스에 속해 있으므로 using지시자를 사용하거나 해당 네임스페이스를 참조해야 한다.
문자열 선언 및 초기화
string str1; // 문자열의 선언
str1 = "C++ Programming"; // 문자열의 초기화
string str2 = "C++"; // 문자열의 선언과 동시에 초기화
string 객체의 경우 문자열을 배열 형태로 선언하지 않고 단순한 변수로 선언한다.
따라서 길이를 명시해주지 않아도 된다는 장점이 있다. 위의 예제에서 str1은 길이가 0인 객체를 선언하고 후에 문자를 초기화하면 자동으로 문자열 str1의 길이를 조절하는 것이다.
string dog;
cout << "현재 dog 변수의 길이는 " << dog.length() << "입니다." << endl;
dog = "Navi";
cout << dog << "! 정말 이쁜 이름이네요!" << endl;
cout << "현재 dog 변수의 길이는 " << dog.length() << "입니다." << endl;
cout << "강아지 이름의 첫 글자는 바로 " << dog[0] << "입니다.";
현재 dog 변수의 길이는 0입니다.
Navi! 정말 이쁜 이름이네요!
현재 dog 변수의 길이는 4입니다.
강아지 이름의 첫 글자는 바로 N입니다.
위의 예제에서 확인할 수 있듯이, string 객체로 만든 문자열도 배열처럼 인덱스를 통해 접근할 수 있다.
정말 좋다… 길이에 대해 고려하지 않아도 되고 배열처럼 인덱스에 접근할 수도 있고.
추가적으로 string 클래스의 length()메소드나 size()메소드를 이용하면 string 객체의 현재 길이를 알 수 있다.
문자열 처리
C++에서 string 객체를 이용한 문자열 처리는 문자형 배열을 이용하는 방식보다 훨씬 간편하다.
C언어세너 문자형 배열 사이에 대입을 할 경우에는 strcpy() 함수를 사용해야 하지만, string 객체를 이용한 문자열에서는 대입 연산자(=)를 활용해 간단하게 수행할 수 있다.
string str1 = "C++ is Cool!";
string str2;
str2 = str1; // 문자열 대입 연산
cout << str2;
C++ is Cool!
또한 string 객체를 이용하면 복합 대입 연산자(+=)나 append() 메소드를 이용해 손쉽게 추가나 제거를 할 수 있다.
string str1 = "C++ is ";
string str2 = "Cool! and funny!";
string str3;
str3 = str1 + str2; // 문자열 결합 연산
cout << str3 << endl;
str1 += str2; // 문자열 추가 연산
cout << str1;
C++ is Cool! and funny!
C++ is Cool! and funny!
문자열 입출력
string 객체를 이용한 문자열의 입력에는 cin객체를, 출력에는 cout 객체를 사용할 수 있다.
단, cin 객체를 이용한 문자열의 입력은 한 단어 단위로 수행된다는 특징이 있다.
따라서 문자열을 한 행(line)씩 읽고 싶을 때는 getline() 함수를 사용해야 한다.
string name, subject;
cout << "자신의 이름을 적어주세요 : ";
getline(cin, name);
cout << "가장 자신있는 과목을 적어주세요 : ";
getline(cin, subject);
cout << name << "님이 가장 자신있어 하는 과목은 바로 " << subject << "입니다!";
자신의 이름을 적어주세요 : 홍길동
가장 자신있는 과목을 적어주세요 : 국어
홍길동님이 가장 자신있어 하는 과목은 바로 국어입니다!
getline() 함수는 첫 번째 매개변수로 cin 객체를 받고, 두 번째 매개변수로는 문자열을 저장할 string 객체 변수를 전달받는다.
3) string 메소드
string 메소드는 string 클래스에 정의된 문자열과 관련된 작업을 할 때 사용하는 메소드이다.
- length() 메소드와 size() 메소드
- append() 메소드
- find() 메소드
- compare() 메소드
- replace() 메소드
- capacity() 메소드와 max_size() 메소드
length() 메소드와 size() 메소드
length() 메소드는 문자열의 길이를 반환하는 메소드이다.
size() 메소드도 length()와 같이 언제나 같은 값을 반환하지만 의미가 약간 다르다.
length() 메소드는 문자열의 길이를 나타내지만,
size() 메소드는 해당 string 객체가 메모리에서 실제 사용하고 있는 크기를 나타낸다.
string str1;
string str2 = "C++ Programming";
cout << "문자열 str1의 길이는 " << str1.length() << "입니다." << endl;
cout << "문자열 str2의 길이는 " << str2.size() << "입니다.";
문자열 str1의 길이는 0입니다.
문자열 str2의 길이는 15입니다.
append() 메소드
append() 메소드는 하나의 문자열의 끝에 다른 문자열을 추가하는 메소드이다.
1. 문자열.append(추가할문자열); // 추가할 문자열을 맨 끝에 추가함.
2. 문자열.append(추가할문자열, 시작위치, 개수); // 추가할 문자열의 시작 위치부터 개수만큼만 맨 끝에 추가함.
3. 문자열.append(개수, 추가할문자); // 추가할 문자를 개수만큼 맨 끝에 추가함
다음은 append() 메소드의 예시 코드이다.
string str1, str2, str3;
str1.append("C++ Programming");
str2.append("C++ Programming", 4, 7);
str3.append(4, 'X');
cout << str1 << endl;
cout << str2 << endl;
cout << str3;
C++ Programming
Program
XXXX
find() 메소드
find() 메소드는 특정 문자열을 찾아 그 시작 위치를 반환하는 메소드이다.
1. 문자열.find(찾을문자열); // 인덱스 0부터 찾을 문자열을 찾아, 그 시작 위치를 반환함.
2. 문자열.find(찾을문자); // 인덱스 0부터 찾을 문자를 찾아, 그 시작 위치를 반환함.
3. 문자열.find(찾을문자열, 시작위치); // 시작 위치부터 찾을 문자열을 찾아, 그 시작 위치를 반환함.
다음은 find() 메소드의 예시 코드이다.
find() 메소드는 해당 문자열에서 찾을 문자열을 찾지 못하면, string::size_type의 string::npos라는 상수를 반환한다.
string str = "C++ Programming";
cout << str.find("Pro") << endl;
cout << str.find('r') << endl;
if (str.find("Pro", 5) != string::npos)
{
cout << "해당 문자열을 찾았습니다.";
}
else
{
cout << "해당 문자열을 찾지 못했습니다.";
}
4
5
해당 문자열을 찾지 못했습니다.
compare() 메소드
compare() 메소드는 두 문자열 간의 내용을 비교하는 메소드이다.
1. str1.compare(str_02) == 0 // str1과 str2이 같을 경우
2. str1.compare(str_02) < 0 // str1이 str2보다 사전 편찬순으로 앞에 있을 경우
3. str1.compare(str_02) > 0 // str1이 str2보다 사전 편찬순으로 뒤에 있을 경우
string str1 = "ABC";
string str2 = "ABD";
if (str1.compare(str2) == 0)
{
cout << str1 << "이 " << str2 << "와 같습니다.";
}
else if (str1.compare(str2) < 0)
{
cout << str1 << "이 " << str2 << "보다 사전 편찬 순으로 앞에 있습니다.";
}
else
{
cout << str1 << "이 " << str2 << "보다 사전 편찬 순으로 뒤에 있습니다.";
}
ABC가(이) ABD보다 사전 편찬 순으로 앞에 있습니다.
replace() 메소드
replace() 메소드는 특정 문자열을 찾아, 그 문자열을 다른 문자열로 대체하는 메소드이다.
문자열.replace(대체할문자열의시작위치, 대체할문자열의길이, 새로운문자열);
// 전달된 시작 위치부터 문자열의 길이만큼을 제거한 후에, 새로운 문자열을 삽입함.
string str1 = "C++ is very nice!";
string str2 = "nice";
string str3 = "awesome";
string::size_type index = str1.find(str2);
if (index != string::npos)
{
str1.replace(index, str2.length(), str3);
}
cout << str1;
C++ is very awesome!
nice의 길이는 4이다. 즉, 4만큼을 새로운 문자열 str3로 대체하겠다는 의미이다.
추가적으로, string::npos는 std::string 클래스에서 사용되는 특별한 상수로, 문자열 내에서 찾고자 하는 부분 문자열이 없을 경우 반환되는 값이다. 해당 코드에서는 string::npos가 아닌 경우 구문을 실행한다고 이해하면 될 듯하다.
capacity() 메소드와 max_size() 메소드
capacity() 메소드는 해당 문자열이 재할당(reallocation) 받지 않고 저장할 수 있는 최대 문자열의 길이를 반환한다.
max_size() 메소드는 해당 문자열이 최대한 대입받으면 가질 수 있는 최대 문자열의 길이를 반환한다.
string str = "C++ Programming";
cout << "문자열 str의 length는 " << str.length() << "입니다." << endl;
cout << "문자열 str의 capacity는 " << str.capacity() << "입니다." << endl;
cout << "문자열 str의 max_size는 " << str.max_size() << "입니다.";
문자열 str의 length는 15입니다.
문자열 str의 capacity는 15입니다.
문자열 str의 max_size는 4611686018427387897입니
'Computer Science > C++' 카테고리의 다른 글
[C++] 함수의 기본 (1) | 2023.11.19 |
---|---|
[C++] 구조체 (0) | 2023.11.13 |
[C++] 배열과 포인터(포인터의 개념,포인터의 연산, 메모리의 동적 할당) (0) | 2023.11.10 |
[C++] 배열과 포인터(1차원 배열,다차원 배열) (0) | 2023.11.05 |
[C++] 제어문 (0) | 2023.10.28 |