대니
danny's blog@dannywon_dev
발행 145 · 대기 173

1인 개발자. 클로드 코드를 팀처럼 굴린다. 매일 겪은 것만 쓴다.

← 버그와 함정

CSV 저장했더니 물음표(?) — UTF-8 변환은 잘못이 없었다

한글은 멀쩡하고 프랑스어·한자만 물음표인 CSV. 0x3F 를 확인하고 나서 순서를 다시 그렸다.

남이 보내준 CSV 를 열었을 때 한글은 멀쩡한데 프랑스어 악센트나 한자만 물음표로 바뀌어 있으면, 보통 인코딩이 어긋났다고 생각한다. 나도 그렇게 생각했다. 그런데 이번엔 파일이 지금 멀쩡한 UTF-8 이었다.

현장에서 정리한 목록 파일(2,068줄)을 CSV 로 받았다. 열어 보니 이런 값들이 있었다.

프랑스 대통령 프랑수아 미테랑 (Fran?ois Mitterrand)
GRAND OFFICIER DE LA L?GION D'HONNEUR
Groupe Soci?t? G?n?rale
서울?도쿄?로스앤젤레스
상하이 서령인사(西?印社)

프랑스어 악센트, 한자 하나, 긴 대시(–). 세어 보니 24개 항목 · 26칸이었다.

물어보니 답이 돌아왔다. "UTF-8로 변환했는데요."

0x3F 가 갈랐다

처음엔 인코딩이 어긋난 줄 알았다. 파일은 EUC-KR 인데 UTF-8 로 읽으면 글자가 뭉개지는, 흔한 경우. 그러면 해결은 「제대로 다시 읽기」다.

그런데 바이트로 열어 보니 이야기가 달랐다.

Fran ? ois        46 72 61 6E [3F] 6F 69 73
                              ↑ 0x3F

0x3F 는 키보드로 치는 그 물음표다. 인코딩이 어긋났을 때 나오는 U+FFFD(�)는 파일 전체에 0개였다. 한글은 정상적인 3바이트 UTF-8 이었다.

즉 파일은 멀쩡하다. 다만 그 안에 이미 물음표가 들어앉아 있었다.

순서를 그려 보니 명확해졌다.

① 표 계산기 화면        François     ← 여기까진 멀쩡
② CSV(쉼표로 분리) 저장   Fran?ois    ← 🔴 여기서 죽었다
③ UTF-8 로 변환         Fran?ois    ← 물음표를 정확하게 옮겼다

②에서 프로그램은 시스템 코드 페이지로 적는다. 확인해 보니 ç É á î 泠 – 는 전부 그 코드에 없는 글자였다. 없는 글자를 만나면 멈추지도, 표시를 남기지도 않고 그냥 물음표를 대신 넣는다.

③은 잘못한 게 없다. 파일에 적힌 걸 그대로 옮겼을 뿐이고, 그때 적혀 있던 게 이미 물음표였다. 변환이 틀린 게 아니라 늦었다.

흑백 복사기로 복사한 뒤 컬러 스캐너로 스캔한 것과 같다. 스캐너는 컬러를 지원하지만, 복사본에 색이 없다.

되살리는 규칙을 좁게 잡았다

앞 회차 파일이 남아 있어서 대조가 가능했다. 그래서 되살리는 도구를 만들었다. 다만 규칙을 아주 좁게 잡았다 — 상대가 오늘 고친 것을 덮어쓰면 안 되기 때문이다.

같은 키·같은 칸에서, 물음표 자리를 빼면 옛 값과 완전히 같을 때만 되살린다.

옛: François Mitterrand
새: Fran?ois Mitterrand      → ? 자리 빼면 동일 → ç 되살림 ✅
새: Fran?ois M. (수정됨)      → 다른 데도 다름 → 손대지 않고 「사람이 봐야 함」으로 남김

26칸 중 25칸이 자동으로 살아났다. 남은 하나는 끝에 줄바꿈이 하나 더 붙어서 길이가 1 달라 걸러졌다. 글자는 ç 하나만 다른데 놓칠 뻔했다. 끝 공백은 내용이 아니니 비교에서 빼도록 고치고 다시 돌려 26칸 전부 복구했다.

안내 문구를 고쳤다

전에는 "CSV 로 저장하지 마세요" 였다. 그러면 왜 안 되는지를 몰라서 「UTF-8로 바꿨으니 괜찮겠지」가 나온다. 실제로 그렇게 나왔다.

저장 목록에 CSV 가 두 개 있습니다. 이름이 거의 같습니다. CSV UTF-8 을 고르세요. 그냥 CSV 는 프랑스어·한자가 물음표로 바뀝니다. 나중에 UTF-8 로 바꿔도 안 돌아옵니다 — 저장하는 그 순간에 이미 사라집니다.

남은 것

이런 손상은 패턴이 뚜렷하다 — Fran?ois 처럼 글자 사이에 낀 물음표다. 진짜 물음표는 괄호 안이나 문장 끝에 온다(하진심(?)).

그래서 다음 판에는 파일을 여는 쪽이 이걸 잡아서 알려주게 할 참이다. 지금은 받는 사람이 눈치채야만 발견되는데, 그러면 아무도 안 볼 때 조용히 지나간다.

← 목록으로