본문 바로가기
컴퓨터/디버깅2

유니코드 사용시 터미널로 출력되지 않는 문자에 의한 오류

by adnoctum 2013. 5. 10.




   파일에 무효한 ID를 텍스트로 저장한 후 읽어 들여서 set 에 넣고, 데이터 처리를 할 때 그 집합에 있으면 넘어가도록 코드를 작성했다. 그런데 최종적으로 보니 그 중 한 개의 무효한 ID가 처리가 되고 있었다. 제일 먼저 생각한 것은 그 ID 가 무효한 ID를 저장하는 파일에 없을 것이라는 것이었으나 확인을 해보니 분명 있었다. 그럼 어떤 이유에서든지 std::set 에 안 들어가나, 해서 set 의 모든 요소를 출력해 보았는데 역시나 있었다. 있는데 왜 처리를 하지? 현재 주어진 ID 가 set 에 있는지를 확인하기 위하여 std::set::count 함수를 사용했기 때문에 그대로 하면서 출력을 해 보았는데 없는 것으로 나온다. 그럼 아예 그 요소를 set 에 집어 넣기 전/후 집합 크기가 변하는지를 보았더니 변한다. 





위 사진에서 3번째의 'SYMPTOM72' 와 마지막 줄의 'SYMPTOM72' 는 같아 보이지 않는가? 그런데 내가 직접 코드에 문자열 'SYMPTOM72'를 집어 넣고 비교를 하면 3번째 줄만 같다고 나오고 6번째 줄은 같다고 나오지 않는다. 아니, 우선 그 전에 저 사진은 집합에 있는 요소를 출력한 것인데 어떻게 집합에 같은 요소가 중복되어 저장되는가? STL의 set 은 중복을 허락하지 않는다 (multiset 은 허락함). 


그래서 다음으로 생각한 것은 비록 터미널로 보기에는 같아 보이지만 실제로는 다른 거다, 라는 것이었다. 무효한 ID 를 저장해 놓은 파일을 열어 봐도 'SYMPTOM72' 라고 적혀 있지만 말이다. 그래서 값을 터미널이 아니라 text file 로 redirection 시켜서 윈도우즈에서 열어 봤더니, 역시나, 마지막 줄의 제일 첫 칸에 이상한 문자가 들러 붙어 있었다. 그것 때문에 위의 3번째 줄과 6번째 줄은 다른 것이었다, 비록 터미널에 출력된 것은 그 이상한 문자들이 출력되지 않아 위 두 줄은 결국 같은 값으로 출력이 되어버렸지만. 


   위와 같은 생각을 할 수 있었던 이유는, 윈도우즈와 리눅스를 번갈아 가면서 사용할 때 인코딩 문제가 계속 귀찮게 하기 때문이고, terminal 설정이 인코딩과 맞지 않으면 글자가 깨져 나오는 것을 자주 경험하기 때문이다. 무효한 ID 파일은 삼바로 걸린 리눅스 서버에 윈도우즈에서 저장해 놓은 것이었고, 모든 코딩 작업은 리눅스 서버에서 하고 있었기 때문에 뭔가 중간에 인코딩이 내가 원하는 것처럼 일관되게 되지 않아서 문제가 생겼을 것이라 추측했다. 잘못된 인코딩에 의한 문제는 그러나 터미널의 옵션까지도 인코딩과 연관되어 있기 때문에 터미널로 출력시 이상이 없어 보일지도 모른다는 생각도 했지. 위의 경우 내용에 한문이 들어 있어서 UTF-8 로 해야 하기 때문에 문제가 생긴 듯 하다. 계속 CP949 를 그대로 써도 문제가 없었는데... 내 서버의 모든 경로에는 한글이 없어서 UTF-8 을 쓸 필요가 없고 그래서 터미널 설정도 그냥 디폴트 상태이다. 이런 여러 상황이 꼬여서 위와 같은 문제가 일어난 것 같다. 


   어쨌든 중요한 것은 '보이는 것이 다가 아니다' 이다.