본문 바로가기

프로그래밍/C++58

Windows 프로그래밍 시 OutputDebugString 사용해 디버깅 정보 출력하기 + 가변인자 받아서 디버깅 정보 출력 OutputDebugString은 Windows 프로그래밍 환경에서 디버깅 세션에 디버깅 정보를 출력하는데 사용되는 함수이다. 이 함수는 프로젝트 문자집합 설정이 멀티바이트냐 유니코드냐에 따라 OutputDebugStringW 또는 OutputDebugStringA로 정의된다. #ifdef UNICODE #define OutputDebugString OutputDebugStringW #else #define OutputDebugString OutputDebugStringA #endif // !UNICODE 먼저 Windows.h 를 포함하고 OutputDebugString 함수를 호출해 디버깅 세션에 출력할 문자열을 넘긴다. ANSI 문자열을 사용하는 경우 그냥 출력하면 되고 유니코드 문자열을 출력할 땐.. 2023. 9. 21.
C++ ] 현재 실행중인 실행파일의 경로 얻기, GetModuleFileName 현재 작업 디렉토리의 경로는 GetCurrentDirectory 함수로 확인할 수 있다. 한편 실행파일이 위치한 경로의 경우 운영체제에 따라 확인하는 방법이 다른데 윈도우에서는 Windows.h 를 포함하고 GetModuleFileName() 함수를 사용하면 현재 실행중인 실행파일의 path를 알 수있다. GetModuleFileName는 유니코드를 사용하냐 ANSI를 사용하냐에 따라 GetModuleFileNameW 또는 GetModuleFileNameA로 정의된다.  wchar_t exePath[MAX_PATH];GetModuleFileName(NULL, exePath, MAX_PATH);wchar_t* folderPath = new wchar_t[wcslen(exePath) + 1];wcscpy(f.. 2023. 9. 19.
C++ ] Winsock2의 bind 함수와 functional 헤더의 std::bind 함수 충돌 방지 Winsock2 라이브러리와 C++ 표준 라이브러리인 functional 헤더를 모두 포함에서 사용하는 경우 bind함수 때문에 충돌할 수 있다. Winsock2의 bind함수는 전역함수로 전역 네임스페이스에 속해있기 때문에 using namespace std; 를 했더라도 전역 bind 함수가 우선 호출된다. Winsock2 bind함수를 호출할 때는 ::bind로 전역 네임스페이스의 bind를 호출하고 C++표준 라이브러리의 std::bind함수를 호출할 때는 std::bind로 명시적으로 써주면 충돌을 피하고 가독성을 높일 수 있다. #include #include int main() { // Winsock2 라이브러리의 bind 함수 호출 ::bind(socket, ...); // C++ 표준 라.. 2023. 9. 17.
C++ ] 멤버 함수 포인터 사용하기 / 함수포인터 대신 std::function 사용 / using으로 별칭 사용 멤버 함수 포인터 선언 returnType (className::*pointerName)(parameterTypes); 멤버 함수 포인터에 함수 주소 대입하기 멤버 함수 포인터에 함수 주소를 대입할 때는 일반 함수포인터와는 다르게 & 연산자를 생략할 수 없다. returnType (className::*pointerName)(parameterTypes) = &className::memberFunctionName; 멤버 함수 포인터 호출하는 법 className object; // 클래스의 인스턴스 생성 (returnType)(object.*pointerName)(arguments); 만약 클래스의 멤버인 멤버 함수 포인터를 멤버 함수 내에서 호출한다면 아래처럼 하면 된다. (this->*functionP.. 2023. 9. 15.
Precompiled Header를 사용해 컴파일 시간 단축하기 1. 프로젝트에서 "stdafx.cpp" 파일을 만든다. stdafx는 Visual Studio에서 사용하는 미리 컴파일된 헤더 파일의 일반적인 이름으로 다른 이름을 사용해도 무방하다. 이 "stdafx.cpp" 파일은 이후 미리 컴파일된 헤더를 생성하는데 사용된다. 2. "stdafx.cpp" 파일에 아래 코드를 추가한다. #include "stdafx.h" 3. "stdafx.h" 파일을 만들고 무겁거나 자주변경되지 않을 헤더파일을 포함시킨다. #pragma once #include #include #include 4. 미리 컴파일된 헤더를 사용할 cpp파일에 아래 코드를 추가한다. #include "stdafx.h" 5. 프로젝트 우클릭 - 설정 - C/C++ - 미리 컴파일된 헤더 설정에서 "미리.. 2023. 9. 15.
char, wchar_t, TCHAR char - 1바이트 문자 또는 숫자를 저장하기 위한 자료형 wchar_t - 2바이트로 문자를 저장하기 위한 자료형 wchar_t myString[] = L"Hello, World!"; TCHAR - 컴파일 환경에 따라 char 또는 wchar_t로 매핑되는 매크로로 Visual Studio 프로젝트 - 속성 - 고급 - 문자집합에서 멀티바이트 문자집합 사용시 char로, 유니코드 문자집합 사용시 wchar_t로 처리된다. TCHAR myString[] = _T("Hello, World!"); 2023. 9. 15.
C++ ] 시스템 명령어 실행 #include #include int main() { const char* command = "ls"; // 실행할 명령어 int result = system(command); // 명령어 실행 if (result == 0) { std::cout 2023. 7. 11.
C++ ] Format-Hex 명령어(Hex 덤프) 직접 구현 #include #include #include #include using namespace std; namespace fs = filesystem; void printhex(char *path) { // ios::binary 플래그를 사용해 이진모드로 파일 열기 ifstream file(path, ios::binary); if (!file) { cerr 2023. 5. 29.
C++ ] Manipulator와 iomanip 헤더 iomanip 헤더에는 스트림을 제어하기 위한 다양한 Manipulator가 포함되어 있다. 스트림은 C++에서 데이터의 입력 및 출력을 처리하는 방식을 말하며, 이를 위해 "iostream" 라이브러리에서 제공하는 클래스와 함수를 사용하는데, Manipulator는 이러한 스트림을 조작하여 데이터의 포맷팅, 출력 형식을 유연하게 지정할 수 있게 한다. endl; 도 개행 문자를 출력하고 버퍼를 비우는 Manipulator이다. #include #include int main() { int number = 12345; double pi = 3.14159; // setw()를 사용하여 출력 폭(width) 지정 std::cout 2023. 5. 28.
C++ ] static_cast와 reinterpret_cast. 그 외 const_cast, dynamic_cast C++에서 C 스타일의 캐스팅은 더 이상 권장되지 않는다. C 스타일 캐스팅은 실수할 여지가 많고 의도하지 않은 형식 변환이 발생할 수 있기 때문에 C++에서는 대신 static_cast, reinterpret_cast, const_cast, dynamic_cast와 같은 명시적인 캐스팅 연산자들을 사용하는 것을 권장한다. 1. static_cast : 정적 캐스트 - 고정된 표준 형식 변환에 사용된다. - 상속 관계가 아닌 타입 간의 변환, 숫자형 타입 간의 변환, 포인터 간의 변환 등. int num = 10; double numDouble = static_cast(num); // int를 double로 변환 2. reinterpret_cast : 재해석 캐스트 - 다른 타입과 포인터 사이의 비트 패.. 2023. 5. 28.
C++ ] 예외처리 try-catch와 throw C++에서 try-catch 문은 예외가 발생할 수 있는 코드 블록을 감싸고, 발생한 예외를 적절하게 처리하는 메커니즘을 제공한다. try-catch 기본 구문 try { // 예외가 발생할 수 있는 코드} catch (예외_유형1& e) { // 예외_유형1에 해당하는 예외 처리 throw; // 다시 던질 수도 있음} catch (예외_유형2& e) { // 예외_유형2에 해당하는 예외 처리 // 다시 던지지 않고 처리하고 끝남} catch (...) { // 기타 모든 예외를 처리하는 블록} try 블록: 예외가 발생할 수 있는 코드를 포함하는 블록. 이 블록 내에서 예외가 발생하면 예외를 던진다.catch 블록: 발생한 예외를 처리하기 위한 블록. catch 블록은.. 2023. 5. 28.
C++ ] filesystem 라이브러리 filesystem 라이브러리는 파일 및 디렉토리 작업을 단순화하고 일반화하는 기능을 제공한다. C++ 17 표준 부터 포함되었으며, gcc/g++ 8 이상 최신 컴파일러에서 지원된다. experimental/filesystem 헤더를 포함하면 이전 버전에서 사용할 수 있을 수도 있다. 📂 현재 경로 출력 #include #include using namespace std; namespace fs = filesystem; int main() { fs::path currentPath = fs::current_path(); cout 2023. 5. 28.
C++ ] JSON 데이터 포맷, rapidjson 라이브러리 사용해 파싱 HTML 삽입 미리보기할 수 없는 소스 JSON(JavaScript Object Notation) 은 데이터 교환을 위한 경량화된 포맷으로, 객체와 배열 등의 데이터 구조를 표현한다. 객체는 중괄호 {} 로 감싸진 key-value 쌍들의 집합이며, 각각의 key는 문자열이고, value는 JSON에서 허용되는 모든 데이터 타입으로 표현될 수 있다. 배열은 대괄호 [] 로 감싸진 값들의 리스트이며, 역시 값은 JSON에서 허용되는 모든 데이터 타입으로 표현될 수 있다. JSON에서 객체의 속성들과 배열의 원소들은 콤마 , 로 구문하며 배열과 객체는 함께 사용할 수 있다. 객체는 배열의 요소로 포함될 수 있는데, 이 경우, 객체는 배열의 요소가 된다. 또한, 객체 안에 배열이 포함될 수 있으며. 이 경우,.. 2023. 5. 14.
C++ ] stream 상속관계 ios_base : 다른 입출력 클래스들의 기반이 되는 클래스로서, 입출력 스트림의 상태와 플래그를 관리 ios : ios_base 클래스를 상속하며, 입출력 스트림의 상태와 플래그를 조작할 수 있는 멤버 함수를 제공 istream : 입력 스트림을 다루는 클래스. 콘솔 입력 및 파일 읽기 등을 다룰 수 있다. ostream : 출력 스트림을 다루는 클래스. 콘솔 출력 및 파일 쓰기 등을 다룰 수 있다. fstream : 파일 입출력을 다루는 클래스. 파일의 읽기 및 쓰기를 다룰 수 있다. stringstream : 메모리상에서 문자열을 읽고 쓰기 위한 클래스. std::string과 유사한 인터페이스를 제공하며, 문자열을 파싱하거나 변환하기 위한 용도로 사용된다. ifstream : 파일 입력에 특화된.. 2023. 5. 14.
C++ ] accumulate 함수 사용시 주의사항 헤더 #include accumulate 함수를 사용하기 위해선 numeric 헤더를 포함한다. 함수 원형 template T accumulate(InputIt first, InputIt last, T init); 구간 [first, last)에 속한 요소들의 합을 구한다. init으로 누적값을 초기화하고, 구간 내의 모든 요소들을 차례대로 더해서 누적값을 반환한다. ❗ 주의할 것은 인자인 first Iterator는 이상이고, last Iterator 미만이다. 때문에 last에는 합을 마지막 요소의 다음 위치를 가르키는 iterator가 온다. vector의 끝까지 연산하는 경우는 vec.end()가 온다. 사용 예시 벡터 내의 모든 요소의 합을 계산한다. #include #include #inclu.. 2023. 3. 31.
C++ ] 2차원 vector 사용법 1. 생성 및 요소 접근 2차원 벡터는 vector 형태로 생성할 때, 첫 번째 인자에 행의 개수를 넣고, 두 번째 인자에는 열의 개수를 넣는다. 또한, 세 번째 인자로는 2차원 벡터의 모든 요소를 초기화할 수 있는 값을 넣는다. 예를 들어, 위의 코드에서는 0으로 모두 초기화한다. 이렇게 생성한 2차원 벡터는 matrix[i][j]와 같이 2개의 인덱스로 요소에 접근할 수 있다. #include #include using namespace std; int main() { vector matrix(3, vector(3, 0)); matrix[0][0] = 1; matrix[1][1] = 2; matrix[2][2] = 3; for(int i=0; i 2023. 3. 31.
C++ ] vector 사용법 vector 사용법 HTML 삽입 미리보기할 수 없는 소스 1. 기본 생성자: 요소의 타입을 지정하지 않으면 빈 벡터가 생성 std::vector vec; // 빈 벡터 생성 2. 초기화 리스트: 중괄호를 이용해 초기 값을 지정 std::vector vec = {1, 2, 3}; // 값이 {1, 2, 3}인 벡터 생성 3. 크기 지정: 생성 시, 초기값이 지정된 요소의 개수를 지정 std::vector vec(5); // 크기가 5이고 모든 값이 0인 벡터 생성 std::vector vec(5, 2); // 크기가 5이고 모든 값이 2인 벡터 생성 4. 복사 생성자: 다른 벡터를 복사하여 생성 std::vector vec1 = {1, 2, 3}; std::vector vec2(vec1); // vec1.. 2023. 3. 31.
C++ ] STL 과 컨테이너 HTML 삽입 미리보기할 수 없는 소스 C++ 언어에서 사용되는 기본 라이브러리로, C++ 컴파일러에 의해 제공된다. 표준 라이브러리는 std 네임스페이스 안에 있는 여러 클래스와 함수를 포함하, STL은 표준 라이브러리의 일부이다. HTML 삽입 미리보기할 수 없는 소스 STL(Standard Template Library)은 C++ 표준 라이브러리의 일부로서, 데이터 구조와 알고리즘을 구현한 템플릿 클래스들의 집합이다. STL은 C++ 개발자들이 높은 수준의 추상화를 이용하여 복잡한 작업을 더 간결하게 표현할 수 있도록 돕는데, 크게 아래와 같은 세 가지 부분으로 구성된다. 1. 컨테이너(Container) 데이터 구조를 구현한 클래스의 집합. 이를 통해 개발자들이 데이터를 쉽게 저장하고 관리할 수 .. 2023. 3. 25.
범위기반 for문, 문자열에서 문자 반복 C++의 범위기반 for문은 C#에서의 foreach와 같으며 사용법은 아래와 같다. for(data type elem : data list) { // do something with elem variable } array, vector, string 등 순회가 가능한 데이터 리스트는 범위기반 for문을 사용해 반복할 수 있다. 일반 for문에 비해 안전하고 간단하지만 index 정보가 없다는 단점이 있다. 문자열에서 문자 반복하기 string 클래스의 length(), size() 메소드를 사용해 일반 for문을 돌릴 수 있지만 아래와 같이 범위기반 for문을 쓸 수도 있다. for (char c : s) for (char& c : s) 위 두 for문의 차이는 위에 것은 s의 element를 c에 복.. 2023. 3. 25.
C 와 C++ 으로 10진수를 2진수로 변환하여 출력하기 C #include int main() { short n = 0; printf("-32,768~32,767 사이의 정수를 입력하세요: "); scanf("%hd", &n); for(int i=15; i>=0; i--){ printf("%d", (n >> i) & 1 ); if(i%4==0) printf(" "); } return 0; } C++ #include #include using namespace std; int main() { short n = 0; coutn; cout 2022. 9. 1.
C++ ] 이중 포인터와 포인터 배열의 차이 이중 포인터 #define _CRT_SECURE_NO_WARNINGS #define _CRTDBG_MAP_ALLOC #include #include int main() { int** pptr; pptr = new int* [4]; pptr[0] = new int[4]; pptr[1] = new int[2]; pptr[2] = new int[5]; pptr[3] = new int; delete[] pptr[0]; delete[] pptr[1]; delete[] pptr[2]; delete pptr[3]; delete[] pptr; _CrtDumpMemoryLeaks(); return 0; } 포인터와 배열은 서로 호환적이다. 그래서 이중 포인터를 이차원 배열로 본다면 행과 열을 가변적으로 둘 수 있는 이차.. 2022. 6. 28.
C++ ] 교통사고 통계자료 필터 프로그램 (2) - vector 사용 , 파입입출력 깃허브 주소 : https://github.com/joeteo/CarAccident main.cpp #include #include "AccidenData.h" #include "AccidentList.h" #include enum { PRINTLIST = 1, SUBTOTAL, EXIT }; using namespace std; int main() { AccidentList handler; handler.readListFromFile(); while(1) { system("cls"); int select; handler.DispMenu(); cin >> select; switch(select) { case PRINTLIST: handler.searchList(); break; case SUBTOTAL:.. 2022. 6. 28.
C++ ] 2021 교통사고 통계자료 필터 프로그램 (1) + 파일 입출력 부분합 기능까지 구현하였다. main.h #pragma once #define COLUMN_NUMBER 13 #define ROW_NUMBER 229 enum { PRINTLIST=1, SUBTOTAL, EXIT }; main.cpp #include #include "AccidenData.h" #include "AccidentList.h" #include "main.h" #include using namespace std; int main() { AccidentList list; list.readListFromFile(); while(1) { system("cls"); int select; list.DispMenu(); cin >> select; switch(select) { case PRINTLIST:.. 2022. 6. 28.
C++ ] 상속을 이용한 주차타워 이전에 사용한 동물호텔과 코드가 거의 같다. main.cpp #include #include "Parking.h" #include using namespace std; int main(void) { Parking parkingHandler; while (true) { int select; system("cls"); parkingHandler.DispMenu(); cout > select; switch (select) { case INBOUND: parkingHandler.InBound(); break; case OUTBOUND: parkingHandler.OutBound(); break; case VIEW: parkingHandler.ViewList(); break; case EXIT: cout 2022. 6. 24.
C++ ] 상속/가상함수를 이용한 동물호텔 main.h #include #include "Hotel.h" #include using namespace std; int main(void) { Hotel hotelHandler; while(true) { int select; system("cls"); hotelHandler.DispMenu(); cout > select; switch (select) { case CHECKIN: hotelHandler.CheckIn(); break; case CHECKOUT: hotelHandler.CheckOut(); break; case VIEW: hotelHandler.ViewList(); break; case EXIT: cout 2022. 6. 24.
C++ ] 입력 버퍼 비우기 , 문자를 입력하면 무한루프에 빠지는 문제 해결 / cin.clear() , cin.ingnore() 정수형 값이 입력되어야 하는데 문자나 문자열이 들어왔을 때 무한루프에 빠지는 문제를 해결하는 방법은 다음과 같다. 대략 아래와 같이 추가해주면 된다. cin.clear() 는 현재 입력이 성공인지 실패인지 나타내는 내부 플래그를 초기화시키는 함수이고 cin.ignore() 가 입력 버퍼를 비우는 함수이다. 두번째 매개변수인 '\n' 문자가 나올때까지 비우는 것(해당 문자 포함)이고, 첫번째 매개변수는 byte 단위로 무시할 문자의 최대 개수를 뜻한다. 정석은 std::numeric_limits::max()을 쓰는 것인데 너무 기니까 INT_MAX를 쓰거나 적당히 큰 값을 입력해주면 된다. cin.clear(); cin.ignore(1000,'\n'); 문자가 입력된 경우를 예외처리 하지 않았을 때 아래와.. 2022. 6. 16.
C++ ] 클래스를 활용한 자판기 프로그램 + 함수 뒤에 붙는 const의 의미 VendingMachine.h#define DRINKNUM 4#define MAXSTOCK 4struct _DRINK { const char* name; int price; int stock;};class VendingMachine{private: _DRINK drink[DRINKNUM]; int MyMoney; int MinPrice;public: VendingMachine(const char* name1, int price1, const char* name2, int price2, const char* name3, int price3, const char* name4, int price4); void showList(); void chkMinPrice(); int GetMoney() const; bo.. 2022. 6. 16.
C++ ] 자판기 프로그램 main.h#ifndef __MAIN_H__#define __MAIN_H__typedef struct {char name[20];int price;int stock;} _DRINK;namespace VendingMachine {int DecideDrinkNum(void);int SettingDrink(_DRINK* drink, const int& num);bool Menu(_DRINK* drink, const int& num, int& money, int min);int MoneyInput(void);}#endif namespace를 사용하여 관련된 함수를 묶었다.  main.cpp#include #include #include #include "main.h"using namespace std;using.. 2022. 6. 16.