연재 완료/C++ Lang 예제코드 모음

Cpp_other_ex 4. Friend

라이피 (Lypi) 2019. 4. 17. 14:18
반응형
header.h
#pragma once
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#define SPA _T(" ")

using std::vector;
using std::string;
using std::stringstream;
using std::getline;
using std::wcout;
using std::endl;
using std::cout;
value.h
#pragma once
#include "header.h"

class token;

class value // 문자열을 저장하는 리스트 구조 클래스
{
private:
	TCHAR*  m_szValue;	//문자열을 저장하는 변수
	value*  m_pNext;	//다음 노드를 가리키는 포인터.
	friend class token;

	//생성자도 private로 하면 token만이 사용할 수 있는 전용 클래스가 된다.
	value(TCHAR*);
	~value();
};


//템플릿 함수는 일단 패스.
static vector& split(const string &s, char delim, vector& elems)
{
	stringstream ss(s);
	string item;
	while (getline(ss, item, delim))
	{
		elems.push_back(item);
	}
	return elems;
}

static vector split(const string &s, char delim)
{
	vector elems;
	split(s, delim, elems);
	return elems;
}
value.cpp
#include "value.h"


	value::value(TCHAR* pData)
	{
		//m_szValue에 메모리를 할당하고 자른 문자열 저장
		int iLength = (int)_tcslen(pData) + 1;
		int iSize = sizeof(TCHAR) * iLength;
		this->m_szValue = new TCHAR[iSize];
		_tcscpy_s(m_szValue, iSize, pData);
		//m_pNext에 nullptr 대입
		m_pNext = nullptr;
	}

	value::~value()
	{
		//할당된 메모리를 해제.
		delete m_szValue;
	}


token.h
#pragma once
#include "value.h"

//예외 클래스 인듯.
class EXP
{
public:
	void show(TCHAR* pData)
	{
		wcout << pData;
	}
public:
	EXP() {};
	~EXP() {};
};


//value의 문자열을 잘라서 리스트로 만드는 클래스
class token
{
private:
	value* m_pToken;
	int    m_iSize;
public:
	void   Show();
	void   Show(value* pValue);
	TCHAR* nth_token(int num);

public:
	token();
	token(TCHAR* pData);
	~token();
};


token.cpp
#include "token.h"

void   token::Show()
{
	// 문자열을 순서대로 출력한다.
	value* pData = m_pToken;
	for (int iCnt = 0; iCnt < m_iSize; iCnt++) {
		wcout << pData->m_szValue << endl;
		pData = pData->m_pNext;
	}
}

void   token::Show(value* pValue)
{
	//매개변수로 받은 문자열을 자른다.
	TCHAR* pszNextToken = 0;
	TCHAR* temp = _tcstok_s(pValue->m_szValue, SPA, &pszNextToken);
	if (temp != NULL) {
		m_pToken = new value(temp);
		value* pLink = m_pToken;
		for (m_iSize = 1; temp = _tcstok_s(0, SPA, &pszNextToken); m_iSize++) {
			pLink->m_pNext = new value(temp);
			pLink = pLink->m_pNext;
		}
	}
	//자른걸 순서대로 출력한다.
	Show();
}


TCHAR* token::nth_token(int num)
{//지정한 순서의 문자열을 출력한다.
	value* cursor = m_pToken;

	for (int iCnt = 1; iCnt < num; iCnt++) {
		if (cursor != 0) {	cursor = cursor->m_pNext; 	}
		else             {	return 0; }
	}

	return cursor->m_szValue;
}

token::token(TCHAR* pData) 
{//매개변수로 받은 문자열을 잘라서 리스트 구조로 저장한다.
	m_iSize = 0;
	TCHAR* temp;
	TCHAR* pszNextToken = 0;

	try {
		//int iNum = 100;
		//int iId = 1;
		//if (iId = 0) { throw(iId); }
		//if (pszNextToken == 0) { //throw (pszNextToken); 
		//	throw EXP(); //exit(1);
		//}
		//iNum /= iId;

		temp = _tcstok_s(pData, SPA, &pszNextToken);
		if (temp != NULL) {
			m_pToken = new value(temp);
			value* pLink = m_pToken;
			for (m_iSize = 1; temp = _tcstok_s(0, SPA, &pszNextToken); m_iSize++) {
				pLink->m_pNext = new value(temp);
				pLink = pLink->m_pNext;
			}
		}
	}

	catch (int iNum) {
		wcout << _T("Error!");
	}
	catch (TCHAR* pszNextToken) {
		wcout << _T("Error!");
		throw(pszNextToken);
	}
	catch (EXP& exp) {
		exp.show((TCHAR*)_T("Error!"));
	}
}

token::token()
{
	m_iSize = 0;
}


token::~token()
{//리스트를 삭제한다.
	value* pDel;
	value* pLink = m_pToken;
	while (pLink != 0) {
		pDel  = pLink;
		pLink = pLink->m_pNext;
		delete pDel;
	}
}

main.cpp
#include "token.h"

int main()
{
	TCHAR buffer[] = L"kgca game academy";

	//방법 1 (금고와 열쇠 관계)
	/*TCHAR buffer[] = L"kgca game academy";
	value vl(buffer);
	token tk;
	tk.Show();*/

	//방법 2
	try {
		token tk(buffer);
		tk.Show();
#ifndef _UNICODE
		cout << _T("Show the 3rd token: ") << tk.nth_token(3) << _T("\n");
#else
		wcout << _T("Show the 3rd token: ") << tk.nth_token(3) << _T("\n");
#endif
	}

	catch (TCHAR* pData)
	{
		wcout << _T("Error");
	}

	vector str = split("one:two::three", ':');
}
반응형