CPP Module 00
CPP Moudle 공통항목
c++ -Wall -Wextra -Werror -std=c+98
로 컴파일- 과제는 모두 C++98 standard를 사용, 이후(C++11 등)에 추가된 기능들은 활용할 수 없음
- class 이름은
UpperCamelCase
포멧을 사용하고 class 코드를 포함한 파일은 해당 class에 맞게 이름지어야함 - 구체적 지시가 있는 것이 아니라면 출력은 항상 개행으로 끝내야함
Norminette
졸업!- 서브젝트에서 특별히 금지한 것이 아니라면 표준 라이브러리를 자유롭게 활용 가능
- 외부 라이브러리는 금지(C++11과 Boost 라이브러리 등),
*printf()
,*alloc()
,free()
도 금지 using namespace <>
와friend
도 금지- STL은 Moudle 08에서만 사용 가능 - 즉,
vector
,list
등의 컨테이너 및<algorithm>
헤더에 정의된 기능들 사용 금지 - 당연히 메모리 누수는 존재해서는 안됨
- Module 02-08에서는 모든 클래스들이
Orthdox Canonical Form
을 따라야 함 - 함수 템플릿이 아닌 이상 헤더파일에 함수 구현부가 포함되어있으면 안됨
- 각 헤더를 서로 독립적으로 사용할 수 있어야하며, 모든 종속성을 포함하면서
double inclusion
을 방지하기 위해include guards
를 사용해야 함 - 필요하다면 코드를 나누기 위해 파일을 추가할 수 있음
Exercise 00 : Megaphone
문제에 관해서는 크게 서술하지 않고, 해당 문제에서 새롭게 배웠거나 다시 익힌 내용들에 대해서만 정리할 예정임
std::strlen
의 경우 <cstring>
헤더파일에 정의되어있음
그러나 mac에서는 <cstring>
헤더파일을 선언하지 않고 <iostrem>
헤더파일만 선언해도 사용이 가능했는데, 이는 컴파일러나 툴에 따라 <iostream>
안에 <cstring>
이 포함되어있을 수 있기 때문
따라서 모든 환경에서도 에러 없이 동작하기를 원하면 정당하게 <cstring>
헤더파일도 넣어주어야 함
해당 주제에 대한 stackoverflow 글 링크
대소문자 변환의 경우 std::toupper
함수를 이용하여 한글자씩 변환해주어야 함
std::toupper
의 반환값은int
형이므로 곧바로std::cout
에 넣었을 경우 정수가 출력되기 때문에char
형으로 변환하는 과정이 필요argv
로 받아오는 문자열을string
으로 변환하고(새로운string
변수를 선언하여argv
의 내용을 대입), c++11이 사용 가능했다면for(auto & x : str)
와 같이 사용하여 더 편리하게 구현할 수 있음std::transform(str.begin(), str.end(), str.begin(), ::toupper);
의 문법도 사용 가능boost::to_upper()
으로 한번에 변경할 수도 있음
Exercise 01 : My Awesome PhoneBook
std::cin >> str
형식으로 문자열을 입력받았을 경우 whitespace가 나올때까지 읽어들임
따라서 ADD adsfasf
의 형식으로 입력해도 str
에는 ADD
만 저장되기 때문에 형식에 맞지 않게 되고, 버퍼에는 여전히 뒷 내용이 남아 문제 발생
- 버퍼를 지우고 싶을 때는
std::cin.ignore(len, '\n')
을 사용
그러므로 std::getline(std::cin, str)
을 사용하여 개행 전까지 한줄을 통째로 읽어들이는 방법을 사용
string.empty()
함수로 개행만 입력되는 경우는 걸러낼 수 있음- 그러나 공백만 읽어들일 경우에도 입력이 되기 때문에 이를 방지하는 것이 필요
- 따라서
string.find_first_not_of()
함수를 활용하여 whitespace를 걸러내는 작업을 수행
해당 주제에 대한 stackoverflow 글 링크
cin.getline()
은 char
형 배열에 문자를 저장
istream
의 멤버함수istream& getline (char* s, streamsize n );
또는istream& getline (char* s, streamsize n, char delim );
의 형태로서 저장할 문자열의 크기 지정이 반드시 필요함
getline()
은string
에 문자를 저장std namespace
에 선언된 일반함수istream& getline (istream& is, string& str);
또는istream& getline (istream& is, string& str, char delim);
의 형태로서 크기 지정 없이 사용 가능
<iomanip>
헤더파일에 있는 조정자들을 활용하면 출력 형식을 지정할 수 있음
std::setw()
: 출력 필드 넓이 지정, 비어있는 부분은 공백으로 처리- 단, 처음 한번의 출력에만 필드 넓이가 지정됨
- 즉
std::setw()
를 한 후std::cout << "abcde" << "12345
를 했을 경우 앞의abcde
문자열에만 필드 넓이가 지정됨에 유의
std::setfill()
: 출력 필드에서 비어있는 부분을 매개변수로 받는 문자로 채움std::setprecision()
: 소수점 출력 길이 지정
while(!(std::cin >> num))
과 같이 사용할 경우
num
이 정상적으로 입력되지 않으면std::cin
이failbit
를 키면서FALSE
를 리턴- 이 경우 버퍼를 건드리지 않기 때문에
while
루프를 통해 돌면 다시 같은 버퍼를 읽으며 똑같은 행동이 무한루프됨 - 따라서 버퍼에 남아있는 것을 지워주는
std::cin.ignore()
함수를 호출해야함 failbit
또한 여전히 켜져있는 상태이기 때문에 이를 꺼주기 위한std::cin.clear()
함수도 호출해야함
Exercise 02 : The Job Of Your Dreams
#ifndef ~ #endif
구문을 #pragma once
가 대체할 수 있음
#ifndef~
구문은 일단 헤더 파일을 연 후ifndef
구문을 통해 사용 여부를 판명#pragma once
는 해당 헤더 파일이 컴파일동안 단 한번만 포함되도록 하므로 중복으로 열리지 않음- 따라서
#pragma once
가 효율이 좀 더 좋기는 하나, 구형 컴파일러에서는 동작하지 않을 수 있음
std::for_each()
: 지시된 함수를 매개변수로 받은 이터레이터로 정의된 범위의 원소들에 적용
std::mem_fun_ref()
: 멤버함수를 f(x)
형태로 바꾸어 함수 객체로 호출
for_each()
함수에서 매개변수로 사용되는 함수는f(x)
형태이기 때문에 이를 활용하기 위해 사용- 단, 인자가 하나인 멤버함수만 지원 가능
시간을 받아오는 용도로 time_t
형 변수와 tm
구조체를 사용
time()
함수로time_t
형 변수에 현재 시간을 나타내는 숫자를 저장- 매개변수가
NULL
일 경우 1970년 1월 1일 0시 0분 0초부터 경과된 시간을 초단위로 나타내는 숫자를 반환 - 매개변수에 다른
time_t
형 변수의 포인터를 넣을 경우 해당 변수의 값을 반환
- 매개변수가
localtime()
함수로time_t
형 변수의 값을 바탕으로tm
구조체에 시간 관련 정보 저장
클래스 내의 변수가 static
으로 선언된 경우 해당 변수의 값은 클래스의 모든 객체가 공유
- 객체 생성 전에도 메모리를 차지하며, 따라서 미리 초기화를 해두어야함
- 이 때 초기화는 클래스 내에서는 불가능하며, 전역 범위에서 이루어짐
- 이는
private
으로 선언된static
멤버 변수에도 똑같이 적용 - 단,
static const
멤버 변수는 객체끼리 공유함과 동시에 값을 변경하는 것이 불가능하므로 클래스 내 초기화가 가능함