2013년 12월 22일 일요일

C++ 날짜 검증 및 특정 포맷으로 반환




EditBox로 날짜를 입력받아야 하는 경우 입력 받은 날짜를 검증하고 특정 포맷으로 변경하는 용도
/************************************************************************
 * 입력된 date를 받아서 
 * yyyyMMdd, yyyyMdd, yyyyMMd, yyyyMd 포맷으로 입력되었다는 가정하에
 * 년/월/일을 검증하여
 * yyyy-mm-dd형식으로 반환
 ************************************************************************/
const char* getDate(string date)
{
//    bool result = true;
    
    int length = date.size();       // 입력된 날짜의 문자열 길이
    
    string iy = date.substr(0, 4);  // 년도 문자열을 추출
    string im;                      // 월 문자열 저장 변수
    string id;                      // 일 문자열 저장 변수
    
    //////////////////////////////////////////////////////////////////////
    // YYYYMD로 입력 되었을 경우의 월/일 문자열
    //////////////////////////////////////////////////////////////////////
    if (length == 6)
    {
        im = date.substr(4, 1);
        id = date.substr(5, 1);
    }
    //////////////////////////////////////////////////////////////////////
    // YYYYMMD || YYYYMDD로 입력 되었을 경우의 월/일 문자열
    //////////////////////////////////////////////////////////////////////
    else if (length == 7)
    {
        im = date.substr(4, 2);
        id = date.substr(6, 1);
        // 만약 추출한 월 데이터가 12보다 크면
        // 월 데이터를 앞자리만 사용하고
        // 뒤 자리수는 일 데이터 앞자리로 옮김
        if (atoi(im.c_str()) > 12)
        {
            im = date.substr(4, 1);
            id = date.substr(5, 2);
        }
    }
    //////////////////////////////////////////////////////////////////////
    // YYYYMMDD로 입력 되었을 경우의 월/일 문자열
    //////////////////////////////////////////////////////////////////////
    else if (length == 8)
    {
        im = date.substr(4, 2);
        id = date.substr(6, 2);
    }
    //////////////////////////////////////////////////////////////////////
    // YYYY-MM-DD로 입력 되었을 경우의 월/일 문자열
    //////////////////////////////////////////////////////////////////////
    else if (length == 10)
    {
        im = date.substr(5, 2);
        id = date.substr(8, 2);
    }
    
    int iYear  = checkYear(iy);   // 년도를 검증
    int iMonth = checkMonth(im);  // 월 검증
    int iDay   = checkDay(id);    // 일 검증

    
    string m = (iMonth < 10) ? "0" + Common::itos(iMonth) : Common::itos(iMonth); // 월 문자열 생성
    string d = (iDay   < 10) ? "0" + Common::itos(iDay)   : Common::itos(iDay);   // 일 문자열 생성
    
    string dateStr = Common::itos(iYear) + "-" + m + "-" + d;
    return dateStr.c_str();
}

년/월/일 검증 함수
// 출생년도를 130년전 부터 현재까지로 한정함
int MemberLayer::checkYear(std::string date)
{
    int n = atoi(date.c_str());
    if (n < year - 130) n = year - 130;
    else if (n > year)  n = year;
    return n;
}

// 입력한 월이 1~12사이의 숫자여야 하고 현재보다 이전이여야 함
int MemberLayer::checkMonth(std::string date)
{
    int n = atoi(date.c_str());
    
    // "03"일 경우 0을 반환함으로 1의자리 수로 한번 확인
    if (n == 0) n = atoi(date.substr(1).c_str());
    
    if (n < 1) n = 1;
    else if (iYear == year)  // 입력한 년도가 현재 년도이면
    {
        if (n > month) n = month;
    }
    else
    {
        if (n > 12) n = 12;
    }
    return n;
}

// 윷년일 때 2월 날짜와 큰달과 작은달의 입력가능 날짜 제한
int MemberLayer::checkDay(std::string date)
{
    int n = atoi(date.c_str());
    if (n == 0) n = atoi(date.substr(1).c_str());
    // 입력한 생년월일이 오늘 이전이어야 함으로 년, 월이 같을 경우
    // 입력한 일이 오늘보다 크면 어제 날짜로 변경
    if (n < 1) n = 1;
    else if (iYear == year && iMonth == month)
    {
        if ( n >= day) n = day - 1;
    }
    else
    {
        if (iMonth == 2)
        {
            // 입력한 월이 2월일 경우
            // 입력 가능 한 계 날짜의 기본값을 28일로 하고
            // 윷년일 경우 29일로 설정
            int max = 28;
            if ((iYear % 4 == 0 && iYear % 100 != 0) || (iYear % 100 == 0 && iYear % 400 == 0))
            {
                max = 29;
            }
            if (n > max) n = max;
        }
        else if (iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11)
        {
            if (n > 30) n = 30;
        }
        else
        {
            if (n > 31) n = 31;
        }
    }
    return n;
}

2013년 12월 19일 목요일

C++ 한글 체크

할글은 2byte가 한글자를 이루며 각 byte의 최상위 bit가 1이다.

때문에 다음과 같이 한글여부를 확인 할 수 있다.

const char* text = "한국";

(text[0] & 0x80) == 1 // 한글
(text[0] & 0x80) != 1 // 한글아님



예:
bool isHangul(const char *text)
{
    bool hangul = true;
    
    for (int i = 0; i < strlen(text); i++)
    {
        if ((text[i] & 0x80) != 0x80)
        {
            hangul = false;
        }
    }
    return hangul;
}

Cocos2d-x에서 EditBox사용하기



1. EditBox사용할 Layer의 Head를 다음과 같이 설정한다.


#ifndef __ProjectName__MemberLayer__
#define __ProjectName__MemberLayer__

#include "Common.h"
#include "cocos-ext.h" // EditBox사용을 위한 추가

USING_NS_CC_EXT; // EditBox사용을 위한 추가

// CCEditBoxDelegate 추가
class MemberLayer:public CCLayer, public CCEditBoxDelegate
{
public:
    virtual bool init();
    
    static CCScene* scene();
    
    CREATE_FUNC(MemberLayer);
    ///////////////////////////////////////////////////////////////
    // EditBox사용을 위한 추가 시작
    ///////////////////////////////////////////////////////////////
    virtual void editBoxEditingDidBegin(CCEditBox* editBox);
    virtual void editBoxEditingDidEnd(CCEditBox* editBox);
    virtual void editBoxTextChanged(CCEditBox* editBox, const std::string& text);
    virtual void editBoxReturn(CCEditBox* editBox);
    ///////////////////////////////////////////////////////////////
    // EditBox사용을 위한 추가 끝
    ///////////////////////////////////////////////////////////////
private:
    void PrepareResources();// 본 페이지에서 사용할 리소스 로드
    void StartLayout();     // 전체 레이아웃 구성
    void PrepareEditBox();  // 이름, 생년월일, 비밀번호 입력 텍스트박스 생성
    
    CCSpriteBatchNode* batchNode;
    
    CCEditBox* Name;        // 이름을 입력할 텍스트박스
    CCEditBox* Birth;       // 생년월일을 입력할 텍스트박스
    CCEditBox* Pwd;         // 비밀번호를 입력할 텍스트박스
};

#endif /* defined(__ProjectName__MemberLayer__) */

2. cpp 파일

#pragma mark -
#pragma mark EditBox
void MemberLayer::PrepareEditBox()
{
    /*****************************************************************
     * 이름 필드
     ****************************************************************/
    Name = CCEditBox::create(CCSizeMake(300, 50), CCScale9Sprite::createWithSpriteFrameName("editBox_bg_normal.png"));
    Name->setPosition(Common::centerPoint());
    Name->setFontColor(ccRED);
    Name->setPlaceHolder("Name");
    Name->setPlaceholderFontColor(ccWHITE);
    Name->setReturnType(kKeyboardReturnTypeDefault);
    Name->setInputMode(kEditBoxInputModeAny);
    Name->setTag(1);
    Name->setDelegate(this);
    this->addChild(Name);
    
    /*****************************************************************
     * 생년월일 필드
     ****************************************************************/
    Birth = CCEditBox::create(CCSizeMake(300, 50), CCScale9Sprite::createWithSpriteFrameName("editBox_bg_complete.png"));
    Birth->setPosition(ccpAdd(Name->getPosition(), ccp(0, 100)));
    Birth->setFontColor(ccRED);
    Birth->setInputMode(kEditBoxInputModePhoneNumber);
    Birth->setDelegate(this);
    this->addChild(Birth);
    /*****************************************************************
     * 비밀번호 필드
     ****************************************************************/
    Pwd = CCEditBox::create(CCSizeMake(300, 50), CCScale9Sprite::createWithSpriteFrameName("editBox_bg_error.png"));
    Pwd->setPosition(ccpAdd(Birth->getPosition(), ccp(0, 100)));
    Pwd->setFontColor(ccRED);
    Pwd->setInputMode(kEditBoxInputModePhoneNumber);
    Pwd->setTag(3);
    Pwd->setReturnType(kKeyboardReturnTypeDone);
    Pwd->setInputFlag(kEditBoxInputFlagPassword);
    Pwd->setDelegate(this);
    this->addChild(Pwd);
}


#pragma mark -
#pragma mark EditBox Virtual Methods
void MemberLayer::editBoxEditingDidBegin(cocos2d::extension::CCEditBox *editBox)
{
    // EditBox편집이 시작될 때 발생하는 이벤트
}
void MemberLayer::editBoxEditingDidEnd(cocos2d::extension::CCEditBox *editBox)
{
    // EditBox편집이 끝날 때 발생하는 이벤트
}
void MemberLayer::editBoxTextChanged(cocos2d::extension::CCEditBox *editBox, const std::string &text)
{
    // EditBox내 Text가 변경될 때 발생하는 이벤트
}
void MemberLayer::editBoxReturn(cocos2d::extension::CCEditBox *editBox){}

EditBoxInputMode (EX) setInputMode(kEditBoxInputModeAny))

  1. kEditBoxInputModeAny = 0,
  2. kEditBoxInputModeEmailAddr,
  3. kEditBoxInputModeNumeric,
  4. kEditBoxInputModePhoneNumber,
  5. kEditBoxInputModeUrl,
  6. kEditBoxInputModeDecimal,
  7. kEditBoxInputModeSingleLine


EditBoxInputFlagType (EX) setInputFlag(kEditBoxInputFlagPassword))

  1. kEditBoxInputFlagPassword = 0,
  2. kEditBoxInputFlagSensitive,
  3. kEditBoxInputFlagInitialCapsWord,
  4. kEditBoxInputFlagInitialCapsSentence,
  5. kEditBoxInputFlagInitialAllCharacters

KeyboardReturnType (EX) setReturnType(kKeyboardReturnTypeSend))

  1. kKeyboardReturnTypeDefault = 0,
  2. kKeyboardReturnTypeDone,
  3. kKeyboardReturnTypeSend,
  4. kKeyboardReturnTypeSearch,
  5. kKeyboardReturnTypeGo