[C언어] KSC5601(EUC-KR)만 입력 받고 나머지는 공백으로 채우기

2022. 3. 2. 15:17귤 IT 코딩

앞서 인코딩 관련된 얘기를 했는데 인코딩의 중요성에 대해서는 설명하고

이를 실제로 코드 상에서 어떻게 적용되는지 설명하지 않아서
인코딩 관련된 내용을 좀 더 작성하고자 합니다.

 

포로그램 상에서 어떤 인코딩을 적용할지 정한 후에는 이에 맞게 입출력이 가능하고 오류처리를 적용하는 것 또한 중요합니다.

어떠한 오류로 인해 입력이 원하지 않는 인코딩 방식으로 들어왔을 때 이를 받아주지 않도록 프로그램을 작성해야 합니다.

 

저는 확실한 안정성을 위해 EUC-KR을 프로그램에 설정했습니다.

그렇기 때문에 db에서도 저장될 때 완성형으로 저장될 수 있게

누가 어떻게 입력을 하던 프로그램은 KSC5601만 받도록 오류처리 해줬습니다.

 

먼저 전체 코드는 아래와 같습니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int filter_ksc5601() {
    unsigned char* str= "죄둉합니다";
    unsigned char* buf;

    int len=strlen((char *)str); //글자 하나당 2byte
    char blank=' ';
    
    buf=calloc(1,len+1);
    strcpy((char*)buf, (char*)str);
    
    for (int i=0; i<len; i++ ){
        /*영어 입력*/
        if(buf[i]< 128){
            if(buf[i] < 31 || buf[i] == 127 || buf[i]== '\'' || buf[i] == '$'){
                buf[i]=blank;
            }
            else{
                buf[i] =str[i];
            }
        }
        else{
            if(i+1==len){
                buf[i]=blank;
            }
            else{
                if(buf[i] >= 0xa1 && buf[i] <= 0xfd && 
                buf[i +1] >= 0xa1 && buf[i+1] <= 0xfe){
                    buf[i]=str[i];
                    buf[i+1]=str[i+1];
                    i++;
                }
                else{
                    buf[i] = blank;
                    buf[i+1] = blank;
                    i++;
                }
            }
        }
        
    }
    
    strcpy((char*)str, (char*)buf);
    free(buf);
    
}

 

코드의 정석은 파라미터로 입력 값을 받아야되지만 따로 테스트를 진행하면서 그냥 입력값은 코드 상에 박아주었습니다.

 

'죄둉합니다'라는 입력이 들어오면

'둉'이라는 ksc5601에 따라 완성형 글자가 아니기 때문에 둉을 공백으로 대체하는 코드입니다.

그럼 '죄 합니다'로 처리되도록 말이죠.

 

저는 아래와 같이 입력된 str 길이를 strlen로 받아서 처리했습니다.

int len=strlen((char*) str);

여기서 프로그램 인코딩 설정을 utf-8로 하셨다면 길이가 달라지고 해당 오류 처리 코드가 정상적으로 돌아가지 않으니 조심하셔야 합니다.

(KSC5601로 설정이 되어 있고 혹시 모를 이상한 값이 왔을 경우를 대비한 오류처리입니다)

 

UTF-8은 한글 한 글자당 3byte이고 euc-kr은 2byte이므로 strlen길이가 다르게 나옴을 유의해야합니다.

 

길이 계산 후에 buf라는 임시 버퍼를 만들어준 후 반복문으로 길이만큼 하나씩 처리해줍니다.

 

먼저 한 글자당 1byte인 영문을 처리합니다.

        if(buf[i]< 128){
            if(buf[i] < 31 || buf[i] == 127 || buf[i]== '\'' || buf[i] == '$'){
                buf[i]=blank;
            }
            else{
                buf[i] =str[i];
            }
        }

영어 외에 다른 문자가 있을 경우에 공백으로 대체해줍니다.

영어가 맞다면 그대로 buf에 담아줍니다.

 

 

다음은 한 글자당 2byte인 한글 처리 부분입니다.

        else{
            if(i+1==len){
                buf[i]=blank;
            }
            else{
                if(buf[i] >= 0xa1 && buf[i] <= 0xfd && 
                buf[i +1] >= 0xa1 && buf[i+1] <= 0xfe){
                    buf[i]=str[i];
                    buf[i+1]=str[i+1];
                    i++;
                }
                else{
                    buf[i] = blank;
                    buf[i+1] = blank;
                    i++;
                }
            }
        }

한글은 2byte이기 때문에 2byte단위로 오류처리를 해줘야 합니다.

 

아래 링크에 있듯이 KSC5601의 영역은 0xa1부터 0xfd까지입니다.

https://kwgyu25it.tistory.com/entry/KSC5601-EUC-KR-UTF-8-Differences

 

KSC5601, EUC-KR, UTF-8 Differences

포로그램에서 입력값을 받을 때 간단한 것 같지만 은근 골치 아프고 문제 되는 부분이 인코딩(encoding) 부분인 것 같습니다. 입력값이 깨진 상태로 입력값을 받으면 처리하는 과정에서 오류가 발

kwgyu25it.tistory.com

그 외에는 모두 공백으로 처리해줍니다.

 

마지막으로 오류처리가 완료된  buf를 str으로 복사해준 후 메모리 free를 해주면 오류처리가 끝나게 됩니다.

 

인코딩의 형태와 특징만 알면 쉽게 오류처리가 가능한 코드입니다.

완성형으로만 입력받는 프로그램을 짜려는 분들에게 많은 도움이 됐으면 좋겠습니다.