2009년 3월 30일 월요일

[C#]주어진 문자(영문이든 한글이든) 원하는 길이 만큼 잘라내기

요즘 작업하는 일 중에 고객사의 요청으로 최대 6자(한글은 3자)까지만 허용할 수 있는 - 즉, 그 길이를 넘어가면 잘라내도록 - 기능을 추가했다.

일단 아래 코드를 먼저 보자.

public string GetWordByByte(string src, int Bytecount)
{
System.Text.Encoding myEncoding
= System.Text.Encoding.GetEncoding("ks_c_5601-1987");
byte[] buf = myEncoding.GetBytes(src);

string strResult = myEncoding.GetString(buf, 0, Bytecount);

if (Bytecount != strResult.Length)
strResult = myEncoding.GetString(buf, 0, Bytecount);

return strResult;
}

인터넷에 돌아다니던 method이다. 어떤 문자이든 일단 method에 넣어 원하는 길이를 넣으면 그 만큼 잘라낸다.

여기서 문제가 발생하는데 한글인지 영문인지 단순 바이트로 구분할 수가 없다는 것이다. 쉽게 다른 블로거님이 작성한 내용을 참고해보자.


"부연 설명
유니코드 인코딩으로 GetBytes를 해보면 한글이나 영문이나 배열을 2칸씩 사용하면서 정보가 들어갑니다. 그러나 영문은 1 byte이기 때문에 2번째 칸에는 무조건 0이란 값만 들어가게 됩니다. 필요없는 데이터가 함께 들어가더군요.

아스키 인코딩으로 해보면 한글을 인식하지 못하기 때문에 한글 정보가 제대로 들어가지 않습니다. 한글을 1바이트 안에 넣으려고 하죠.

하지만 위에서 사용한 인코딩 방법은 한글은 배열을 2칸씩, 영문은 1칸씩 사용하면서 넣어줍니다. 덕분에 문자열이 한글이든 영문이든 바이트 단위로 잘 가져올 수 있더군요."


위의 내용처럼 한글이든 영문이든 같은 크기의 바이트를 사용하기 때문에 바이트 크기로 구분할 수는 없다. (개인적으로 참고한 블로그이니 따로 참고할 자료가 필요하다면 글에 걸려있는 링크를 따라가 보기를 바란다.)
즉, 6자(한글 3자)를 넘기면 무조건 길이에 맞게 잘라내야 한다고 가정해보자. 그러면 한글이 "가나다라바사"이면 분명 "가나다"까지만 check되어 잘라야 하지만 구분할 단순 length로는 판단이되지 않기 때문에 다른 방법이 필요하다는 것이다.

그래서 다음과 같이 풀었다. 아예 code를 보면서 얘기하자.


bool bHangul = false;

char[] cLoginUserID = g_strLoginUserID.ToCharArray(0, g_strLoginUserID.Length);
foreach (char c1 in cLoginUserID)
{
if (char.GetUnicodeCategory(c1) ==
System.Globalization.UnicodeCategory.OtherLetter) // 한글인지 check
{
bHangul = true;
break;
}
else
bHangul = false;
}

if (bHangul)
InsertCommand[iRow].Parameters.Add("@arg_UserId",
OleDbType.VarChar).Value = CommFunc.GetWordByByte(g_strLoginUserID, 6);
else
InsertCommand[iRow].Parameters.Add("@arg_UserId",
OleDbType.VarChar).Value = g_strLoginUserID;

char[] cLoginUserName =
g_strLoginUserName.ToCharArray(0, g_strLoginUserName.Length);
foreach (char c2 in cLoginUserName)
{
if (char.GetUnicodeCategory(c2) ==
System.Globalization.UnicodeCategory.OtherLetter) // 한글인지 check
{
bHangul = true;
break;
}
else
bHangul = false;
}

if (bHangul)
InsertCommand[iRow].Parameters.Add("@arg_UserName",
OleDbType.VarChar).Value = CommFunc.GetWordByByte(g_strLoginUserName, 6);
else
InsertCommand[iRow].Parameters.Add("@arg_UserName",
OleDbType.VarChar).Value = g_strLoginUserName;

위의 code 처럼 char array로 복사하여 문자별로 비교하여 한글인지 check하고 만약 한글자라도 한글이 있다면 그에 맞게 처음 설명한 code를 이용하여 입력된 길이에 맞게 잘라내는 것이다.

위의 code들은 실제 사용되고 있는 code로 사용자 id와 name을 한글은 3자, 영문은 6자를 넘어가면 잘라서 입력하기 위해 만들어진 code이다.
InsertCommand는 OleDbCommand[] InsertCommand로 sql 명령문을 실행하기 위한 프로시져이다. 그리고 arg_UserId, arg_UserName는이 sql에서 사용하기 위한 아규먼트이다.

0 개의 댓글:

댓글 쓰기