-- 유니코드로 언어변경
ALTER DATABASE [KISS] COLLATE Korean_Wansung_Unicode_CI_AS

posted by 뚱2
출처 : ㅠㅠ 잊어버렸습니다.


인터넷에서 유니코드 한글 위치와 초성 중성 종성을 찾는 알고리즘을 찾았는데 브라우져를 꺼버렸네요 ㅠㅠ
암튼 위의 이미지를 참조해서 아이폰에서 사용할 요량으로 만들어 봤습니다.
알고리즘에 오타 문제가 있습니다.
초성부분에 int((strCode - 0xAC00) / 28 * 21) 이라고 했는데 "28*21" 부분을 "(28*21)" 괄호로 묶어줘야 합니다.
//ChosungUtil.h
#define HANGUL_START_CODE   0xAC00
#define HANGUL_END_CODE     0xD79F

@interface ChosungUtil : NSObject
{
    NSArray *chosung;
    NSArray *jungsung;
    NSArray *jongsung;
}

@property (nonatomic, retain) NSArray *chosung;
@property (nonatomic, retain) NSArray *jungsung;
@property (nonatomic, retain) NSArray *jongsung;

// 입력문자열를 초성과 비교해서 NSComparisonResult를 반환한다.
- (NSComparisonResult) compare:(NSString *)source withChoungString:(NSString *)search;
// 입력문자열을 초성으로 변환시킨다.
- (NSString*) stringChosung:(NSString *) source; 

@end

//ChosungUtil.m
#import "ChosungUtil.h"

@implementation ChosungUtil

@synthesize chosung, jungsung, jongsung;


- (NSComparisonResult) compare:(NSString *)source withChoungString:(NSString *)search
{
    return [[self stringChosung:source] compare:search];
}

- (NSString*) stringChosung:(NSString *) source
{
    NSMutableString *result = [NSMutableString string];
    
    for (NSUInteger i = 0; i < [source length]; i++) {
        NSInteger unicodeChar = [source characterAtIndex:i];
        
        // 한글인지 검색
        if ( HANGUL_START_CODE <= unicodeChar && unicodeChar <= HANGUL_END_CODE )
        {
            NSInteger chosungIndex  = (NSInteger)((unicodeChar - HANGUL_START_CODE) / (28*21));
            // 중성, 종성은 현재 필요없다.
            //            NSInteger jungsungIndex = (NSInteger)((unicodeChar - HANGUL_START_CODE) % (28*21) / 28);
            //            NSInteger jongsungIndex = (NSInteger)((unicodeChar - HANGUL_START_CODE) % 28);
            
            [result appendFormat:@"%@", [chosung objectAtIndex:chosungIndex]];
        }
        
    }
    
    return result;
}


-(id)init
{
    self = [super init];
    if ( self != nil )
    {
        // 초기화 
        chosung = [[NSArray arrayWithObjects:
                   @"ㄱ",@"ㄲ",@"ㄴ",@"ㄷ",@"ㄸ",@"ㄹ",@"ㅁ",
                   @"ㅂ",@"ㅃ",@"ㅅ",@"ㅆ",@"ㅇ",@"ㅈ",@"ㅉ",
                   @"ㅊ",@"ㅋ",@"ㅌ",@"ㅍ",@"ㅎ",nil] retain];

        jungsung = [[NSArray arrayWithObjects:
                     @"ㅏ",@"ㅐ",@"ㅑ",@"ㅒ",@"ㅓ",@"ㅔ",
                     @"ㅕ",@"ㅖ",@"ㅗ",@"ㅘ",@"ㅙ",@"ㅚ",
                     @"ㅛ",@"ㅜ",@"ㅝ",@"ㅞ",@"ㅟ",@"ㅠ",
                     @"ㅡ",@"ㅢ",@"ㅣ",nil] retain];
        jongsung = [[NSArray arrayWithObjects:
                     @"",@"ㄱ",@"ㄲ",@"ㄳ",@"ㄴ",@"ㄵ",@"ㄶ",
                     @"ㄷ",@"ㄹ",@"ㄺ",@"ㄻ",@"ㄼ",@"ㄽ",@"ㄾ",
                     @"ㄿ",@"ㅀ",@"ㅁ",@"ㅂ",@"ㅄ",@"ㅅ",@"ㅆ",
                     @"ㅇ",@"ㅈ",@"ㅊ",@"ㅋ",@" ㅌ",@"ㅍ",@"ㅎ",nil] retain];     
    }
    
    return self;
}


-(void)dealloc
{
    [chosung release];
    [jungsung release];
    [jongsung release];
    
    [super dealloc];
}

@end



//사용방법
-(IBAction)clickedButton:(id)sender 
{
    NSLog(@"%@", hangulField.text);
    
    ChosungUtil *util = [[[ChosungUtil alloc] init] autorelease];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"변환결과" 
                                                    message:[util stringChosung:hangulField.text] 
                                                   delegate:self
                                           cancelButtonTitle:nil 
                                          otherButtonTitles:@"닫기", nil];
    [alert show];
    [alert release];
}




 
posted by 뚱2

Visual Studio 2008에서 데이터베이스에 Input, Output 하는 프로그램을 만들었습니다.

프로그램에서 Oracle에 Insert하면은 정상적으로 한글이 보이는데

파일을 읽어서 Oracle에 Insert하면은 깨지는 현상이 나타났습니다.

결국 해결은

Visual Studio 2008의 로케일을 변경해서 해결했습니다.

// 로케일을 설정
_tsetlocale(LC_ALL, _T("korean"));
// 또는 #pragma로도 가능하다.
#pragma setlocale("korean")



또한 #pragma
posted by 뚱2

물론 MultiByteToWideChar API를 사용하면  Ansi->Unicode로 전환할수 있습니다.

MultiByteToWideChar를 보시면 알겠지만 인자가 많습니다. ㅡㅡ;

int MultiByteToWideChar(
  UINT CodePage, 
  DWORD dwFlags,         
  LPCSTR lpMultiByteStr, 
  int cbMultiByte,       
  LPWSTR lpWideCharStr,  
  int cchWideChar        
);

이럴때 MFC에서만 사용할수 있는 꼼수

char szBuffer[] = "Ansi 스트링 입니다.";
CString strUnicode = (CString)szBuffer;

이렇게만 하면 끝났습니다.
다만 그냥 컨버팅 되는게 아니라
프로그램 베이스가 Unicode 기반으로 작성된 프로그램에서
Ansi 문자열을 Unicode 기반으로 컨버팅 하실때 편하게 사용하실수 있습니다.

소스를 쫓아 들어가보면 알겠지만

형변환 내부적으로 MultiByteToWideChar 함수를 호출하고 있습니다.

// 데이터 길이 가져오는 함수
static int __cdecl GetBaseTypeLength( _In_z_ LPCSTR pszSrc ) throw()
{
    // Returns required buffer size in wchar_ts
    return ::MultiByteToWideChar( _AtlGetConversionACP(), 0, pszSrc, -1, NULL, 0 )-1;
}

// 데이터 변환 하는 함수
static void __cdecl ConvertToBaseType( _Out_cap_(nDestLength) LPWSTR pszDest
, _In_ int nDestLength, _In_z_ LPCSTR pszSrc, _In_ int nSrcLength = -1) throw()
{
    // nLen is in wchar_ts
    ::MultiByteToWideChar( _AtlGetConversionACP()
                          , 0, pszSrc, nSrcLength, pszDest, nDestLength );
}

그런데 막상 해보면 글자가 한글이 깨집니다.
이유는 http://msdn.microsoft.com/ko-kr/library/w1sc4t4k(VS.80).aspx
문자열 변환 보시면 알겠지만 기본 코드 페이지가 변경되었습니다.


문자열 변환

Visual C++ 6.0의 ATL 3.0 및 그 이전 버전에서는 atlconv.h의 매크로를 사용하는 문자열 변환이 항상 시스템의 ANSI 코드 페이지(CP_ACP)를 사용하여 수행되었습니다. Visual C++ .NET의 ATL 7.0부터는 _CONVERSION_DONT_USE_THREAD_LOCALE이 정의되지 않은 경우 문자열 변환이 현재 스레드의 기본 ANSI 코드 페이지를 사용하여 수행됩니다. _CONVERSION_DONT_USE_THREAD_LOCALE이 정의된 경우에는 이전과 같이 시스템의 ANSI 코드 페이지가 사용됩니다.

CW2AEX 등의 문자열 변환 클래스를 사용하면 변환에 사용할 코드 페이지를 해당 생성자에 전달할 수 있습니다. 코드 페이지를 지정하지 않으면 해당 클래스에서는 매크로와 동일한 코드 페이지를 사용합니다.

자세한 내용은 ATL and MFC String Conversion Macros를 참조하십시오.


결국 컨버전 할때 내부적으로

inline UINT WINAPI _AtlGetConversionACP() throw()
{
#ifdef _CONVERSION_DONT_USE_THREAD_LOCALE
    return CP_ACP;
#else
    return CP_THREAD_ACP;
#endif
}

이 함수를 호출하는데 _CONVERSION_DONT_USE_THREAD_LOCALE 매크로가 없기 때문에 CP_THREAD_ACP 코드
페이지가 작성됩니다.

그래서 매크로를 프로젝트에 추가(Property Pages->Configuration Properties->C/C++->Preprocessor->Preprocessor Definitions)해주고

Rebuild All 해서 사용하시면 됩니다.

posted by 뚱2