Topic 4: 문자열 처리 함수 🛠️
🎯 학습 목표
- C++ 문자열의 기본 함수들을 이해할 수 있다
- 문자열 검색과 수정 기능을 활용할 수 있다
- 문자열과 숫자 간 변환을 수행할 수 있다
📚 문자열 라이브러리 소개
“string 클래스는 문자열을 쉽게 다룰 수 있는 강력한 도구상자입니다!”
C++의 string
클래스는 문자열 처리를 위한 다양한 멤버 함수를 제공합니다.
🔍 문자열 검색 함수
1. find() 함수
개념: 문자열 내에서 특정 문자나 부분 문자열을 찾습니다.
#include <iostream>
#include <string>
using namespace std;
int main() {
string text = "Hello, World! Hello, C++!";
// 1. 문자 찾기
size_t pos = text.find('W');
if (pos != string::npos) {
cout << "'W'의 위치: " << pos << endl; // 7
}
// 2. 문자열 찾기
pos = text.find("Hello");
cout << "첫 번째 'Hello' 위치: " << pos << endl; // 0
// 3. 특정 위치부터 검색
pos = text.find("Hello", 5); // 5번 인덱스부터 검색
cout << "두 번째 'Hello' 위치: " << pos << endl; // 14
// 4. 찾지 못한 경우
pos = text.find("Python");
if (pos == string::npos) {
cout << "'Python'을 찾을 수 없습니다." << endl;
}
return 0;
}
💡 핵심 포인트:
find()
함수는 찾은 위치의 인덱스를 반환- 찾지 못하면
string::npos
반환 (매우 큰 값) - 대소문자를 구분함
2. rfind()와 기타 검색 함수
#include <iostream>
#include <string>
using namespace std;
int main() {
string text = "apple, banana, apple, cherry";
// rfind: 뒤에서부터 검색
size_t lastApple = text.rfind("apple");
cout << "마지막 'apple' 위치: " << lastApple << endl; // 15
// find_first_of: 여러 문자 중 하나라도 처음 나타나는 위치
size_t firstVowel = text.find_first_of("aeiou");
cout << "첫 번째 모음 위치: " << firstVowel << endl; // 0
// find_last_of: 여러 문자 중 하나라도 마지막으로 나타나는 위치
size_t lastComma = text.find_last_of(",");
cout << "마지막 쉼표 위치: " << lastComma << endl; // 21
return 0;
}
✂️ 문자열 수정 함수
1. substr() - 부분 문자열 추출
#include <iostream>
#include <string>
using namespace std;
int main() {
string text = "Hello, World!";
// substr(시작위치, 길이)
string part1 = text.substr(0, 5); // "Hello"
string part2 = text.substr(7); // "World!" (끝까지)
string part3 = text.substr(7, 5); // "World"
cout << "part1: " << part1 << endl;
cout << "part2: " << part2 << endl;
cout << "part3: " << part3 << endl;
// 날짜 문자열 파싱 예제
string date = "2024-03-15";
string year = date.substr(0, 4);
string month = date.substr(5, 2);
string day = date.substr(8, 2);
cout << "년: " << year << ", 월: " << month << ", 일: " << day << endl;
return 0;
}
2. replace() - 문자열 치환
#include <iostream>
#include <string>
using namespace std;
int main() {
string text = "I love Java programming";
// replace(시작위치, 길이, 새문자열)
text.replace(7, 4, "C++"); // "Java"를 "C++"로 교체
cout << text << endl; // "I love C++ programming"
// find와 함께 사용
string sentence = "The cat is on the mat";
size_t pos = sentence.find("cat");
if (pos != string::npos) {
sentence.replace(pos, 3, "dog");
}
cout << sentence << endl; // "The dog is on the mat"
return 0;
}
3. insert()와 erase()
#include <iostream>
#include <string>
using namespace std;
int main() {
string text = "Hello World";
// insert(위치, 문자열) - 삽입
text.insert(5, " Beautiful");
cout << text << endl; // "Hello Beautiful World"
// erase(시작위치, 길이) - 삭제
text.erase(5, 10); // " Beautiful" 삭제
cout << text << endl; // "Hello World"
// 특정 문자 모두 제거하기
string numbers = "1,2,3,4,5";
size_t pos = 0;
while ((pos = numbers.find(',')) != string::npos) {
numbers.erase(pos, 1);
}
cout << numbers << endl; // "12345"
return 0;
}
🔄 문자열과 숫자 변환
1. 문자열을 숫자로 변환
#include <iostream>
#include <string>
using namespace std;
int main() {
// stoi: string to int
string str1 = "123";
int num1 = stoi(str1);
cout << "문자열 \"123\" → 정수 " << num1 << endl;
// stod: string to double
string str2 = "3.14159";
double num2 = stod(str2);
cout << "문자열 \"3.14159\" → 실수 " << num2 << endl;
// stol: string to long
string str3 = "1000000";
long num3 = stol(str3);
cout << "문자열 \"1000000\" → long " << num3 << endl;
// 변환 실패 처리
try {
string invalid = "abc123";
int num = stoi(invalid); // 예외 발생!
} catch (const invalid_argument& e) {
cout << "변환 실패: 올바른 숫자 형식이 아닙니다." << endl;
}
return 0;
}
2. 숫자를 문자열로 변환
#include <iostream>
#include <string>
using namespace std;
int main() {
// to_string 함수 사용
int num1 = 42;
double num2 = 3.14159;
string str1 = to_string(num1);
string str2 = to_string(num2);
cout << "정수 42 → 문자열 \"" << str1 << "\"" << endl;
cout << "실수 3.14159 → 문자열 \"" << str2 << "\"" << endl;
// 문자열 결합에 활용
int score = 95;
string message = "당신의 점수는 " + to_string(score) + "점입니다.";
cout << message << endl;
return 0;
}
🧹 문자열 정리 함수
1. 공백 제거하기
#include <iostream>
#include <string>
using namespace std;
// 앞 공백 제거
string ltrim(string str) {
size_t start = str.find_first_not_of(" \t\n\r");
return (start == string::npos) ? "" : str.substr(start);
}
// 뒤 공백 제거
string rtrim(string str) {
size_t end = str.find_last_not_of(" \t\n\r");
return (end == string::npos) ? "" : str.substr(0, end + 1);
}
// 양쪽 공백 제거
string trim(string str) {
return rtrim(ltrim(str));
}
int main() {
string text = " Hello World ";
cout << "원본: '" << text << "'" << endl;
cout << "ltrim: '" << ltrim(text) << "'" << endl;
cout << "rtrim: '" << rtrim(text) << "'" << endl;
cout << "trim: '" << trim(text) << "'" << endl;
return 0;
}
2. 대소문자 변환
#include <iostream>
#include <string>
using namespace std;
int main() {
string text = "Hello World!";
// 대문자로 변환
string upper = text;
for (int i = 0; i < upper.length(); i++) {
if (upper[i] >= 'a' && upper[i] <= 'z') {
upper[i] = upper[i] - ('a' - 'A');
}
}
cout << "대문자: " << upper << endl; // "HELLO WORLD!"
// 소문자로 변환
string lower = text;
for (int i = 0; i < lower.length(); i++) {
if (lower[i] >= 'A' && lower[i] <= 'Z') {
lower[i] = lower[i] + ('a' - 'A');
}
}
cout << "소문자: " << lower << endl; // "hello world!"
// 문자 하나씩 변환 예제
string text2 = "C++ Programming";
cout << "원본: " << text2 << endl;
// 대문자로 변환
for (int i = 0; i < text2.length(); i++) {
if (text2[i] >= 'a' && text2[i] <= 'z') {
text2[i] = text2[i] - ('a' - 'A');
}
}
cout << "대문자 변환: " << text2 << endl;
return 0;
}
📊 문자열 정보 함수
#include <iostream>
#include <string>
using namespace std;
int main() {
string text = "Hello, World!";
// length() 또는 size(): 문자열 길이
cout << "길이: " << text.length() << endl; // 13
cout << "크기: " << text.size() << endl; // 13 (같은 기능)
// empty(): 빈 문자열 확인
string empty_str = "";
cout << "빈 문자열? " << (empty_str.empty() ? "예" : "아니오") << endl;
// clear(): 문자열 비우기
string temp = "temporary";
temp.clear();
cout << "clear 후: '" << temp << "'" << endl; // ""
// capacity(): 할당된 메모리 크기
string str = "Hello";
cout << "길이: " << str.length() << ", 용량: " << str.capacity() << endl;
// resize(): 크기 변경
str.resize(10, 'X'); // 10글자로 늘리고 'X'로 채움
cout << "resize 후: '" << str << "'" << endl; // "HelloXXXXX"
return 0;
}
🎮 실습: 간단한 텍스트 처리기
#include <iostream>
#include <string>
using namespace std;
// 문자열에서 특정 문자의 개수 세기
int countChar(string text, char ch) {
int count = 0;
for (int i = 0; i < text.length(); i++) {
if (text[i] == ch) {
count++;
}
}
return count;
}
// 문자열의 단어 수 세기 (공백 기준)
int countWords(string text) {
int count = 0;
bool inWord = false;
for (int i = 0; i < text.length(); i++) {
if (text[i] != ' ' && !inWord) {
count++;
inWord = true;
} else if (text[i] == ' ') {
inWord = false;
}
}
return count;
}
// 간단한 CSV 파싱 (최대 10개 항목)
void parseCSV(string csvData) {
string items[10]; // 최대 10개 항목 저장
int itemCount = 0;
string current = "";
for (int i = 0; i < csvData.length() && itemCount < 10; i++) {
if (csvData[i] == ',') {
items[itemCount++] = current;
current = "";
} else {
current += csvData[i];
}
}
// 마지막 항목 추가
if (!current.empty() && itemCount < 10) {
items[itemCount++] = current;
}
// 결과 출력
cout << "CSV 파싱 결과 (" << itemCount << "개 항목):" << endl;
for (int i = 0; i < itemCount; i++) {
cout << i + 1 << ". " << items[i] << endl;
}
}
int main() {
cout << "=== 간단한 텍스트 처리기 ===" << endl;
// 1. CSV 데이터 파싱
string csvData = "apple,banana,cherry,date";
cout << "\n원본 CSV: " << csvData << endl;
parseCSV(csvData);
// 2. 문자 개수 세기
string text = "Hello, World! How are you?";
cout << "\n텍스트: " << text << endl;
cout << "공백 개수: " << countChar(text, ' ') << "개" << endl;
cout << "느낌표 개수: " << countChar(text, '!') << "개" << endl;
cout << "쉼표 개수: " << countChar(text, ',') << "개" << endl;
// 3. 단어 수 세기
string sentence = "The quick brown fox jumps over the lazy dog";
cout << "\n문장: " << sentence << endl;
cout << "단어 수: " << countWords(sentence) << "개" << endl;
// 4. 문자열에서 첫 단어와 마지막 단어 찾기
string fullName = "Hong Gil Dong";
size_t firstSpace = fullName.find(' ');
size_t lastSpace = fullName.rfind(' ');
if (firstSpace != string::npos) {
string firstName = fullName.substr(0, firstSpace);
string lastName = fullName.substr(lastSpace + 1);
cout << "\n전체 이름: " << fullName << endl;
cout << "첫 단어: " << firstName << endl;
cout << "마지막 단어: " << lastName << endl;
}
return 0;
}
💭 생각해보기
Q1. find() vs rfind()
언제 find()
를 사용하고 언제 rfind()
를 사용하는 것이 좋을까요?
💡 답변
find()
: 앞에서부터 검색 - 첫 번째 등장 위치가 필요할 때rfind()
: 뒤에서부터 검색 - 마지막 등장 위치가 필요할 때
예시: 파일 경로에서 파일명만 추출하려면 rfind('/')
를 사용하는 것이 효율적
Q2. string::npos의 의미
string::npos
는 왜 -1이 아니라 특별한 값을 사용할까요?
💡 답변
string::npos
는 size_t
타입의 최대값입니다. size_t
는 부호 없는 정수 타입이므로 -1을 표현할 수 없습니다. 대신 가장 큰 값을 “찾지 못함”의 의미로 사용합니다.
Last updated on