바람이 머문 언덕

문자를 연산자로 추가 삭제하기 본문

컴퓨터 IT/C++ 언어

문자를 연산자로 추가 삭제하기

알 수 없는 사용자 2010. 1. 14. 20:13
반응형
operator를 이용 해서 연산자를  재정의 해서 문자를 연산자로 추가 삭제하는 예제를 만들어 보았습니다.
이 기능은 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;
}