======C++ 스터디 #8: 문자열====== | 시간 | 2021년 6월 29일 화요일 20:00 ~ 22:00 | | 장소 | ZOOM | | 참가자 | - | {{youtube>qsmXJ2GSSxc?medium}} 출처: 천인국, "어서와 C++는 처음이지!", INFINITY BOOKS \\ https://blockdmask.tistory.com/308 [개발자 지망생] =====1. string 클래스===== C++은 객체 지향 언어입니다. 이번 여름 방학부터 본격적으로 객체 지향 방법에 대해 배우게 될 것입니다. \\ 문자열은 문자들의 나열입니다. C 언어에서는 문자열을 char형 배열로 나타내고 strcat()과 같은 어려운 함수 등을 사용해 문자열을 다룹니다. 하지만 C++ 언어에서는 string 클래스를 이용하여 문자열을 쉽게 저장하고 처리할 수 있습니다. string은 문자열을 나타내기 위하여 작성된 클래스입니다. string 클래스 안에는 문자열 저장 및 허리에 필요한 변수들과 함수들이 정의되어 있습니다. =====2. 문자열 선언===== ====2.1. 문자열 선언 예시==== #include #include using namespace std; int main() { string s1 = "Hello"; string s2 = {"World!"}; string s3(3, 'a'); cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; return 0; } =====3. 문자열의 결합(+ 연산자 이용)===== string 클래스를 사용하면 문자열들을 '+' 연산자를 이용하여 간단하게 결합할 수 있습니다. ====3.1 문자열의 결합 예시==== #include #include using namespace std; int main() { string s1 = "Slow", s2 = "steady"; string s3 = "the race."; string s4; s4 = s1 + " and " + s2 + " wins " + s3; cout << s4 << endl; return 0; } =====4. 문자열의 비교(비교 연산자 이용)===== string 클래스를 사용하면 비교 연산자(==, >, <)들을 이용하여 문자열이 서로 같은지, 사전 순서로 어떤 문자가 앞에 오는지 알 수 있습니다. ====4.1 문자열의 비교 예시==== #include #include using namespace std; int main() { string s1 = "a", s2 = "b"; if (s1 == s2) cout << "동일한 문자열입니다." << endl; else cout << "동일한 문자열이 아닙니다." << endl; if (s1 > s2) cout << "s2이 앞에 있습니다." << endl; else if(s1 =====5. getline 사용===== cin을 사용해 string을 입력하면 공백 문자가 있으면 입력이 멈춥니다. 예를 들어 "고려대학교 기계공학부"를 입력하면 "고려대학교"만 입력되고 나머지 단어들은 입력을 대기하게 됩니다. 이때 getline() 함수를 사용하여 띄어쓰기가 포함된 한 줄을 전부 읽어줄 수 있습니다. ====5.1. getline 사용 예시==== #include #include using namespace std; int main() { /*string s1; cin >> s1; cout << s1 << endl;*/ string s2; getline(cin, s2); cout << s2 << endl; return 0; } =====6. 문자열과 배열===== 문자열을 배열처럼 다룰 수 있습니다. 만약 s="String"이란 문자열이 있다면 s[0]='S', s[5]='g' 이런식으로 표현할 수 있습니다. ====6.1. 문자열과 배열 예시==== #include #include using namespace std; int main() { string s = "apple"; for (int i = 0; i < 5; i++) cout << s[i] << endl; return 0; } =====7. string 클래스 멤버 함수 호출===== |^**멤버 함수** ^ **설명** ^| |s.insert(pos, s2) | s의 pos위치에 s2를 삽입| |s.find(s2) | s에서 문자열 s2가 발견되는 첫번째 인덱스를 반환| |s.at(pos) |s에서 pos 위치에 있는 문자를 반환 | |s.erase(pos, len) |s의 pos 위치부터 len만큼을 삭제 | |s.empty() |s가 비어있으면 true를 반환 | ====7.1. insert, find==== #include #include using namespace std; int main() { string s1 = "String", s2 = "Test"; string s3 = "t"; cout << s1.insert(2, s2) << endl; cout << s1 << endl; cout << s1.find(s3) << endl; return 0; } ====7.2. at, erase, empty==== #include #include using namespace std; int main() { string s1 = "String"; cout << s1.at(2) << endl; cout << s1.erase(2, 2) << endl; cout << s1 << endl; s1.clear(); cout << s1.empty() << endl; cout << s1 << endl; return 0; } ====7.3. append==== #include #include using namespace std; int main() { string str1("String"); cout << str1 << endl; str1.append(" Test"); cout << str1 << endl; str1.append(" Test Test", 3, 5); cout << str1 << endl; str1.append(" Test Test", 7); cout << str1 << endl; str1.append(3, 'T'); cout << str1 << endl; return 0; } =====8. 번외-변수 생성===== ====8.1. rand 사용==== #include #include using namespace std; int main() { cout << rand() << endl; cout << rand() << endl; cout << rand() << endl; cout << rand() << endl; cout << rand() << endl; return 0; } ====8.2. srand 사용==== #include #include using namespace std; int main() { cout<<"1. rand()"< ====8.3. time 사용==== #include #include #include using namespace std; int main() { cout << time(NULL) << endl; srand((unsigned int)time(NULL)); cout << rand() % 10 << endl; return 0; } =====9. 예제===== ====9.1. 예제(1): 행맨 게임 만들기==== **행맨 게임은 빈칸으로 구성된 문자열이 주어지고 사용자는 문자열에 들어갈 글자들을 하나씩 추축해서 맞추는 게임이다.** \\ {{activity:public:2021:cpp:1.png}}\\ Tip. 다음은 빈칸으로 주어질 단어 예시이다. 난수를 사용해 실행할 때마다 다른 문제가 출제되게 만든다. 2.1에서 소개한 방법을 이용해 빈칸으로 구성된 문자열을 만든다. \\ string solution; string list[] = { "the", "c++", "programming", "language", }; srand((unsigned int)time(NULL)); int n = rand() % 4; solution = list[n]; string guess(solution.length(), '_'); [정답 예시] #include #include #include #include using namespace std; int main() { char ch; string solution; string list[] = { "the", "c++", "programming", "language", }; srand((unsigned int)time(NULL)); int n = rand() % 4; solution = list[n]; string guess(solution.length(), '_'); while (true) { cout << guess << endl; cout << "글자를 입력하시오: "; cin >> ch; for (int i=0;i< solution.length();i++) { if (ch == solution[i]) { guess[i] = ch; } } if (solution == guess) { cout << solution << endl; cout << "성공하였습니다.!"; break; } } return 0; } ====9.2. 예제(2): 가장 긴 문자열 출력==== **사용자로부터 문자열 5개를 읽어서 가장 긴 문자열을 화면에 출력한다.**\\ {{activity:public:2021:cpp:2.png}}\\ Tip. string의 배열을 만들어서 사용자의 입력을 저장하고 string 클래스의 멤버 함수인 size()를 사용한다. \\ [정답 예시] #include #include using namespace std; int main() { string s1[5]; string max = s1[0]; for (int i = 0; i < sizeof(s1) / sizeof(string); i++) { cout << "문자열을 입력하시오: "; cin >> s1[i]; if (s1[i].size() > max.size()) max = s1[i]; } cout << "제일 긴 문자열: " << max << endl; return 0; } ====9.3. 예제(3): 난수 생성==== **0부터 9까지의 난수를 100번 생성하여 가장 많이 생성된 수를 출력하는 프로그램을 작성하시오.** \\ {{activity:public:2021:cpp:3.png}}\\ [정답 예시] #include #include #include using namespace std; int main() { int list[10] = {}; int max = 0; srand((unsigned int)time(NULL)); for (int i = 0; i < 100; i++) { int num = rand() % 10; list[num]++; if (list[num] >= list[max]) max = num; } cout << "가장 많이 생성된 수: " << max; return 0; } ====9.4. 예제(4): 철자 교정 프로그램==== **간단한 철자 교정 프로그램을 작성하여 보자. 문자열을 입력으로 받아서 문자열 안에 마침표가 있으면 문자열의 첫 번째 문자가 대문자인지를 건사한다. 만약 대문자가 아니면 대문자로 변환한다. 또한 문장의 끝에 마침표가 존재하는지를 검사한다. 역시 마침표가 없으면 넣어준다. 즉 입력된 문자열이 "c++ is easy"라면 "C++ is easy."로 변환하여 화면에 출력한다.** \\ {{activity:public:2021:cpp:4.png}}\\ [정답 예시] #include #include using namespace std; int main() { string s; cout << "문자열을 입력하시오: "; getline(cin, s); s[0] = toupper(s[0]); if (s[s.length() - 1] != '.') s += "."; cout << "결과 문자열: " << s << endl; return 0; } ====9.5. 예제(5): 문자가 나타나는 빈도 출력==== **사용자로부터 받은 문자열에서 각각의 문자가 나타나는 빈도를 계산하여 출력하는 프로그램을 작성하시오.(단, 영어 소문자만 입력된다.)** \\ {{activity:public:2021:cpp:5.png}}\\ Tip. 문자는 아스키코드로 표현되고 0에서 255까지의 값을 가진다. 따라서 크기가 256인 정수 배열을 선언하고 다음과 같이 반복 루프를 통하여 빈도를 구한다. \\ int counter[256] = { 0 }; string s; cout << "문자열을 입력하시오: "; getline(cin, s); for (int i = 0; i < s.size(); i++) { counter[s[i]]++; } [정답 예시] #include #include using namespace std; int main() { int counter[256] = { 0 }; string s; cout << "문자열을 입력하시오: "; getline(cin, s); for (int i = 0; i < s.size(); i++) { counter[s[i]]++; } for (int i = 'a'; i <= 'z'; i++) { cout << (char)i << ": " << counter[i] << endl; } return 0; } ====9.6. 예제(6): 암호의 안전 여부 판단==== **사용자로부터 암호를 입력받는다. 사용자의 암호가 해킹에 대하여 안전한지의 여부를 검사한다. 만약 암호 안에 대문자, 소문자, 숫자가 모두 들어있으면 안전한 암호로 간주한다. 만약 사용자의 암호가 3가지 종류의 문자를 다 가지고 있지 않으면 프로그램은 보안을 위하여 더 강한 암호를 고려하라고 제안한다.** \\ {{activity:public:2021:cpp:6-1.png}}\\ {{activity:public:2021:cpp:6-2.png}}\\ Tip. bool 자료형을 이용해 해결하는 방법도 있다. \\ [정답 예시] #include #include using namespace std; int main() { string pw; int low = 0, up = 0, num = 0; cout << "암호를 입력하세요: "; getline(cin, pw); bool is_lower = false, is_upper = false, is_numeric = false; for (int i = 0; i < pw.length(); i++) { if (pw[i] >= 'a' && pw[i] <= 'z') is_lower = true; else if (pw[i] >= 'A' && pw[i] <= 'Z') is_upper = true; else if (pw[i] >= '0' && pw[i] <= '9') is_numeric = true; } if ((is_lower && is_upper && is_numeric) == true) { cout << "안전합니다." << endl; } else cout << "안전하지 않습니다." << endl; return 0; } ====9.7. 예제(7): 애나그램(anagram) 게임==== **단어 애나그램(anagram) 게임을 작성해보자. 영어 단어를 이루는 글자들이 뒤죽박죽 섞인 것을 받아서 순서대로 재배치하는 게임을 애나그램 게임이라 한다.** \\ {{activity:public:2021:cpp:7.png}}\\ Tip. 문자열 안의 글자들을 섞으려면 난수가 필요하다. 2개의 난수를 발생시켜서 그 위치의 글자들을 서로 바꾸면 된다. 이것을 문자열의 길이만큼 반복한다. 물론 난수의 범위는 문자열의 안이어야 한다. \\ [정답 예시] #include #include #include #include using namespace std; int main() { string s1 = "apple"; string s2 = s1; string answer; char temp; srand((unsigned int)time(NULL)); for (int i = 0; i < 5; i++) { int n1 = rand() % 5; int n2 = rand() % 5; temp = s1[n1]; s1[n1] = s1[n2]; s1[n2] = temp; } while (1) { cout << s1 << "은 어떤 단어가 스크램블된 것일까요?"; cin >> answer; if (s2 == answer) { cout << "축하합니다." << endl; break; } } return 0; }