======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;
}