바람이 머문 언덕
문자를 연산자로 추가 삭제하기 본문
이 기능은 mfc의 CString, 베이직과 같은 고급 언어에서는 익숙한 기능으로 operator 를 이용해 연산자를 재정의 해놓으면
문자열을 가지고 작업 할 때 편한게 사용 할 수 있습니다.
고급 언어에서 사용하는 기능들 처럼 여러 가지 함수를 넣지는 안고 간단히 operator를 가지고 연산자를 재정의 하는
방법과 이해를 돕기 위해서 몇 가지 연산자를 사용해서 만들어 보았습니다.
앞에 operator를 설명하면서 간단히 동적 메로리 할당을 이용해서 문자 열을 추가 삭제 가능 하도록 만들어 보았는데
그 때는 아무런 이상이 없었는데 동적 메모리를 사용하니 에러가 나는 부분이 있었습니다.
전역 변수는 파괴자를 프로그램 종료시 한번만 호출하는 걸로 알고 있는데 동적으로 메모리를 할당 받아서 =, - 연산을
하다보니 전역 오브젝트 변수의 파괴자가 여러번 호출 되는지 동적 메모리가 해제되어서 프로그램 에러가 났습니다.
아마 +, - 연산을 할 때 오브젝트 변수를 리턴 하는데 이 값을 reference 변수로 받아서 reference 변수가 소멸 될 때
전역 변수로 선언 cbuf의 동적 메모리가 해제 되었던 것 같다.
그래서 state 변수를 선언하여 +, -가 호출 되는 것을 카운트하여 프로그램 종료시 전역 오브젝트 변수의 동적 메모리가
프로그램 종료시 한 번만 해제 되도록 했습니다.
class NString
{
public:
int state; // 전역 전역 오브젝트 변수의 cbuf 동적 메모리 해제를 프로그램 종료 때 한번만 삭제를 위해서
char* cbuf; // 문자를 저장하기 위해서
NString(void);
NString(char *buf);
~NString(void);
void operator= (char *); // 문자열을 복사 할 때
void operator= (NString &); // 오브 젝트의 문자열을 복사 할 때
void operator+= (char *buf); // 문자열 추가
void operator+= (NString &buf); // 오브젝트의 문자열 추가
NString operator+ (NString &); // 문자열을 합친다.
NString operator- (NString &); // 문자열을 제거 한다.
void operator-= (char *buf);
void operator-= (NString &buf);
};
=================================================================================================================
#include "StdAfx.h"
#include "NString.h"
#include <string.h>
#define null 0
NString ObTemp; // +,- 연산자을 할 때 사용 할 임시 보관을 위한 전역 변수
NString::NString(void)
{
cbuf = null;
state =1;
}
NString::NString(char *buf)
{
cbuf = new char[strlen(buf)+1];
strcpy(cbuf, buf);
state =1;
}
NString::~NString(void)
{
if(cbuf && state ==1) // 전역 변수 ObTemp.cbuf 가 여러 번 삭제 되는 것을 방지하기 위해서서
{
delete cbuf;
}
state--; // 전역 오부젝트 변수의 동적 메모리 cbuf를 프로그램 종료시 삭제를 위해서
}
void NString::operator= (char *buf) // 문자열 복사
{
if(cbuf != null) delete cbuf; // 오브젝트에 저장되어 있던 문자열 삭제
cbuf = new char[strlen(buf)+1];
strcpy(cbuf, buf);
}
void NString::operator= (NString &a) // 문자열 복사
{
if(cbuf != null) delete cbuf;
cbuf = new char[strlen(a.cbuf)+1];
strcpy(cbuf, a.cbuf);
}
void NString::operator+= (NString &buf) // 문자열 추가
{
char* a;
if(cbuf)
{
a= new char[strlen(cbuf)+strlen(buf.cbuf)+1];
strcpy(a, cbuf);
delete cbuf;
strcat(a, buf.cbuf);
}
else
{
a= new char[strlen(buf.cbuf)+1];
strcpy(a, buf.cbuf);
delete cbuf;
}
cbuf = a;
}
void NString::operator+= (char* buf) // 문자열 추가
{
char* a;
if(cbuf)
{
a= new char[strlen(cbuf)+strlen(buf)+1];
strcpy(a, cbuf);
delete cbuf;
strcat(a, buf);
}
else
{
a= new char[strlen(buf)+1];
strcpy(a, buf);
}
cbuf = a;
}
NString NString::operator+ (NString &a) // 문자열을 합친다.
{
char* tb = ObTemp.cbuf;
char* buf = new char[strlen(cbuf)+strlen(a.cbuf)+1];
strcpy(buf, cbuf);
strcat(buf, a.cbuf);
if(tb) delete tb;
ObTemp.cbuf = buf;
ObTemp.state++; // 전역 오브젝트 변수의 동적 메모리 삭제를 방지하기 위해서
return ObTemp;
}
NString NString::operator- (NString &a) // 문자열을 뒤부터 제거
{
int ik = strlen(cbuf), ib=strlen(a.cbuf), s = 0;
char* buf =new char[ik+1];
strcpy(buf, cbuf);
if(ib>0)
{
ib--; ik--;
int n=ib, k=0, i=ik;
while(i>=0)
{
if(buf[i]==a.cbuf[n])
{
while(buf[i] == a.cbuf[n])
{
if(n == 0)
{
s = 1; // 제거 할여고 하는 문자가 있어면
k = i; // 제거 할 문자의 처음 위치
break;
}
i--; n--;
}
if(s == 1)
{
for( ; buf[k+ib] !='\0'; k++) // 제거 할 문자위에 뒤에 있는 문자를 덮어 쓴다.
{
buf[k] = buf[k+ib+1];
}
buf[ik-ib]='\0';
ObTemp.cbuf = new char[strlen(buf)+1];
strcpy(ObTemp.cbuf, buf);
delete buf;
break;
}
else
{
n=ib;
continue;
}
}
i--;
}
}
if(buf && s==0) delete buf;
ObTemp.state++; // 전역 오브젝트 변수의 동적 메모리 삭제를 방지하기 위해서
return ObTemp;
}
void NString::operator-= (char *buf)
{
int ik = strlen(cbuf), ib=strlen(buf);
if(ib>0)
{
ib--;
int n=ib, k=0, s = 0, i=ik;
while( i>=0 )
{
if(cbuf[i]==buf[n])
{
k = i;
while(cbuf[i] == buf[n])
{
if(n==0)
{
s =1;
break;
}
i--;--n;
}
if(s == 1)
{
for(k-=ib; cbuf[k+ib] !='\0'; k++)
{
cbuf[k] = cbuf[k+ib+1];
}
cbuf[ik-ib]='\0';
break;
}
else
{
n=ib;
continue;
}
}
i--;
}
}
}
void NString::operator-= (NString &a)
{
int ik = strlen(cbuf), ib=strlen(a.cbuf);
if(ib>0)
{
ib--;
int n=ib, k=0, s = 0, i=ik;
while( i>=0 )
{
if(cbuf[i]==a.cbuf[n])
{
k = i;
while(cbuf[i] == a.cbuf[n]) //
{
if(n==0)
{
s =1;
break;
}
i--;--n;
}
if(s == 1)
{
for(k-=ib; cbuf[k+ib] !='\0'; k++)
{
cbuf[k] = cbuf[k+ib+1];
}
cbuf[ik-ib]='\0';
break;
}
else
{
n=ib;
continue;
}
}
i--;
}
}
}
===========================================================================================
//실행 예
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "NString.h"
int main(int argc, _TCHAR* argv[])
{
NString a("123"), c="789", b="456", d="0";
printf("%s \n", a.cbuf);
a=a+b+c;
printf("%s \n", a.cbuf);
a-="123";
printf("%s \n", a.cbuf);
a="123";
printf("%s \n", a.cbuf);
a=a+b+c-b+d-c;
printf("%s \n", a.cbuf);
system("PAUSE");
return 0;
}