GSI

stl string trim 구현하기

STL 2007. 9. 6. 14:43 |

string을 사용하고 있지만.. trim이 없는듯 합니다. -.- 혹시 알면 댓글.. 부탁 드림..

아래와 같은 프로그램 경로가 있다고 햇을때 프로그램 파일 부분만 잘라 낼려고 할대
아래와 같은 코드를 사용했습니다.

원본 패스 : d:\gsi_project\projectx\bin\AttachImageMakerd.exe
결과 패스 : d:\gsi_project\projectx\bin

//초기화

string appPath = argv[0];
string appdir;
appdir.clear();
//뒷 부분을 잘라 내야 하기 때문에 우선 뒤쪽에서 '\'를 찾는다.

int findidx = (int)appPath.rfind('\\');

//찾은 인덱스를 사용해서 잘라낸다.

appdir = string(appPath, 0, findidx); //appPath : 풀 패스, 0 : 시작인덱스, findidx : 끝 인덱스

이상...

Posted by gsi
:

float, int 등을 string 변환 - ostringstream 이용

#include <sstream>

std::ostringstream outstream;
outstream << 숫자등등
std::string str = outstream .str()

Posted by gsi
:

for_each()를 사용할때

//클래스

class Widget {
public:
 Widget(int var) : value(var) {}

 void Test() {
  cout << "값 " << value << endl;
 }

public:
 int value;
};

//함수 선언

void Test(Widget& w)
{
 cout << w.value << endl;
}

//사용하는곳

 vector<Widget> vw;

 vw.push_back(Widget(1));
 vw.push_back(Widget(2));
 vw.push_back(Widget(3));
 vw.push_back(Widget(4));
 vw.push_back(Widget(5));

//일반 함수는 Test 또는 ptr_fun(Test) 라고 하면 됩니다.

 for_each(vw.begin(), vw.end(), Test);
 for_each(vw.begin(), vw.end(), ptr_fun(Test));

//클래스 내부의 함수를 접근 할 때는 vw의 형태가 참조냐 포인터냐에 따라서

//달라 집니다. 참조 이기 때문에 mem_fun_ref(&Widget::Test)를 사용합니다.
 for_each(vw.begin(), vw.end(), mem_fun_ref(&Widget::Test));

 vector<Widget*> lpw;

 lpw.push_back(new Widget(1));
 lpw.push_back(new Widget(2));
 lpw.push_back(new Widget(3));
 lpw.push_back(new Widget(4));
 lpw.push_back(new Widget(5));

//포인터이기 때문에 mem_fun(&Widget::Test)를 사용하게 되지요.

 for_each(lpw.begin(), lpw.end(), mem_fun(&Widget::Test));

Posted by gsi
:

vector <> 에 포인터 객체를 넣게 되면 많은 부분 불편한게 생긴다.
메모리의 삭제에 있어서 다른 처리를 해야 하기 때문이다.

하지만 boost의 shared_ptr를 사용하면 아주 편하게 구현이 됩니다.
관련 내용 : http://crowmania.cafe24.com/crowmania/?p=50

[헤더]
#include <vector>
using namespace std;
#include <boost/shared_ptr.hpp>

//테스트할 클래스 구성
class CMemTest
{
public:
 CMemTest() : _val(0)
 {
 }
 CMemTest(int val)
 {
  _val = val;
 }
 ~CMemTest()
 {
 
 }

 int _val;
};

//부스터에 맞는 타입디파인
typedef boost::shared_ptr<CMemTest> SPMemTest;

[코드]
vector<SPMemTest> m_SPMemTest;

SPMemTest sp1 = SPMemTest(new CMemTest);
m_SPMemTest.push_back(sp1);
m_SPMemTest.push_back(sp1);
m_SPMemTest.pop_back();
m_SPMemTest.pop_back();

//이렇게 하면 삭제가 됩니다.
//다른 방법으로 사용하면 아래도 가능하죠
m_SPMemTest.push_back(SPMemTest(new CMemTest(10)));
m_SPMemTest.push_back(SPMemTest(new CMemTest));

//값을 사용할때
. 가 아니고 -> 를 사용해야 합니다.
m_SPMemTest[0]->_val = 10;

//erase와 clear만 사용하면 자동으로 메모리 삭제 됨

count = m_SPMemTest.size();
m_SPMemTest.erase(m_SPMemTest.begin());
count = m_SPMemTest.size();

m_SPMemTest.clear();

Posted by gsi
:

stl 문중에서 아마도 vector를 가장 개인적으로 선호 한다.
이론적인 내용은 우선 접어 두고.. (책을 보면 안다 ^^)

기존에 내가 했던 작업은 vector와 for문을 많이 사용했다.
이번에 accumulate, for_each를 공부 하면서 많은 부분 간소화 시키고
가독성과 범용성을 갖출수 있는 방법을 찾아 봤다.
class 의 객체를 vector에 추가 해서 작업 할때 vector의 배열 정보를 사용해서
특정 변수의 값을 다르게 변경할 작업이 많이 생긴다.

//헤더에 필요한 헤더파일을 추가한다.

#include <vector>
#include <map>
#include <algorithm>
#include <numeric>

using namespace std;

아래와 같은 클래스가 있다고 하자.

class Element {
public:
 DWORD UID;
 INT  Price;
 int  Count;
 DWORD Res_ID;

 //생성자
 Element(DWORD uid, INT price, int count, DWORD res_id, ) :
  UID(uid),
  Price(price),
  Count(count),
  Res_ID(res_id),
 {
 }

 //operator
 bool operator==(const Element& e) const {
  return (UID == e.UID) ? true : false;
 }
};

위의 코드에서 price는 가격을 뜻하고, count는 수량을 뜻한다.
Res_ID는 해당 오브젝트의 리소스 아이디라고 가정을 하자.
아래와 같은 작업을 할려고 한다.

1. Count가 음수인 요소들의 개수를 얻어 오고 싶다.
2. Count가 음수인 요소들의 Price의 총 합을 얻고 싶다.
3. Count가 음수인 요소들의 Res_ID의 목록을 얻고 싶다.

기존에 for문을 사용하게 되면 코드의 량도 늘어 나고 보기에도 좀 그렇다.
아래와 같은 accumulate 함수를 작성하고 활용하면 자연스럽게 구현이 가능하다.

//카운터가 0보다 작은 요소들의 개수
int count_minus_element_sum (int count, const Element& t1 ) {
 if(t1.Count < 0)
  count++;

 return count;
}

//카운터가 0보다 작은 요소들의 총금액
int count_minus_element_price_sum (int price, const Element& t1 )
{
 if(t1.Count < 0) {
  price += (abs(t1.Count) * t1.Price);
 }

 return price;
}

//카운터가 0보다 작은 resid를 추출
vector<DWORD>& count_minus_resid ( vector<DWORD>& v, const Element& t1 )
{
 if(t1.Count < 0) {
  v.push_back(t1.Res_ID);
 }
 return v;
}

//for_each - cout << resid << endl
void display_resid ( const DWORD& ri )
{
 cout << ri << endl;
}

//벡터 테스트
 vector< Element > m_ElementList;

//요소를 추가한다.

 m_ElementList.push_back(Element(100, 100, 1, 2000));
 m_ElementList.push_back(Element(101, 100, 2, 2001));
 m_ElementList.push_back(Element(102, 100, 3, 2002));
 m_ElementList.push_back(Element(103, 100, -1, 2003));
 m_ElementList.push_back(Element(104, 100, 0, 2004));
 m_ElementList.push_back(Element(105, 100, -2, 2005));
 m_ElementList.push_back(Element(106, 100, -3, 2006));
 m_ElementList.push_back(Element(107, 100, -1, 2007));
 m_ElementList.push_back(Element(108, 100, 2, 2008));
 m_ElementList.push_back(Element(109, 100, 3, 2009));
 m_ElementList.push_back(Element(110, 100, 6, 2010));

//음수인 요소의 개수의 총 합을 구한다.

 int count = accumulate(m_ElementList.begin(), m_ElementList.end(), 0, count_minus_element_sum);

//음수인 요소의 가격의 총 합을 구한다.
 int price = accumulate(m_ElementList.begin(), m_ElementList.end(), 0, count_minus_element_price_sum);

//음수인 요소의 Res_ID의 목록을 구한다.
 vector<DWORD> m_ResID; //목록을 담을 배열을 선언한다.
 m_ResID.clear(); //클리어
 m_ResID = accumulate(m_ElementList.begin(), m_ElementList.end(), m_ResID, count_minus_resid);

//담겨진 요소의 Res_ID를 화면에 출력해 본다.

 for_each(m_ResID.begin(), m_ResID.end(), display_resid);

위와 같이 accumulator를 잘만 사용하면 아주 다양한 효과를 볼 수 있을거 같다.
총 합을 구하거나 모든 요소의 특징을 살펴 본다거나 하는 형태의 작업에 아주 탁월하다.

for_each는 for문을 사용하는 번거로움을 조금 해소해 줄수 있다.

Posted by gsi
: