본문 바로가기
C++, MFC

[C++/MFC] 텍스트 파일의 인코딩 확인하는 방법

by dev_drive 2022. 9. 16.
반응형
 

유니코드 인코딩 BOM(Byte Order Mark) 정리

문자 인코딩(Encoding)이란? 문자 인코딩은 사용자가 입력한 문자나 기호를 컴퓨터가 이해할 수 있는 것으로 만드는 것을 의미합니다. 1. 인코딩의 종류 텍스트 파일을 저장할 때 인코딩 형식을 선

dev-drive.tistory.com

* 우선 인코딩이나 BOM의 개념을 모르신다면 위 글을 읽어보시고 오시는 것을 추천드립니다. 

 

 

많은 종류의 인코딩이 있지만 가장 많이 사용하는 ANSI, UTF-8, UTF-8(BOM), UTF-16 LE,  UTF-16 BE 5가지를 구분하는 방법에 대해 설명해 드리겠습니다.

 

 

🔽 파일의 BOM(Byte Order Mark)를 읽어서 인코딩 구분

enum encoding { ANSI, UTF8, UTF8_BOM, UTF16_LE, UTF16_BE };
encoding enc = ANSI;

CString sFilePath = _T("txt파일경로");
CFile file;
if (file.Open(sFilePath, CFile::modeRead))
{
	int nLen = (int)file.GetLength();
	char* pData = new char[nLen + 1];
	memset(pData, 0, (nLen + 1));

	LONG nReadSize = file.Read(pData, nLen);
	if (nReadSize == nLen)
	{
		unsigned char UTF16_LE_BOM[] = { 0xFF, 0xFE };
		unsigned char UTF16_BE_BOM[] = { 0xFE, 0xFF };
		unsigned char UTF8_8BOM[] = { 0xEF, 0xBB, 0xBF };

		unsigned char* lpHeader = (unsigned char*)pData;

		if (lpHeader[0] == UTF16_LE_BOM[0] && lpHeader[1] == UTF16_LE_BOM[1])
			enc = encoding::UTF16_LE;
		else if (lpHeader[0] == UTF16_BE_BOM[0] && lpHeader[1] == UTF16_BE_BOM[1])
			enc = encoding::UTF16_BE;
		else if (lpHeader[0] == UTF8_8BOM[0] && lpHeader[1] == UTF8_8BOM[1] && lpHeader[2] == UTF8_8BOM[2])
			enc = encoding::UTF8_BOM;
		else
		{
			// 위 3가지 경우가 아닐 경우 파일 내용을 분석해 UTF8, Ansi 구분
			if (IsUTF8((const void*)lpHeader, nLen))
				enc = encoding::UTF8;
		}
	}
	delete[] pData;
}
file.Close();

 

 

🔽 BOM(Byte Order Mark)이 없을 때 UTF8과 ANSI구분

bool CMyClass::IsUTF8(const void* pBuffer, long size)
{
	bool bUTF8 = true;
	unsigned char* start = (unsigned char*)pBuffer;
	unsigned char* end = (unsigned char*)pBuffer + size;
	while (start < end)
	{
		if (*start < 0x80) // (10000000)[output][/output]
		{
			start++;
		}
		else if (*start < (0xC0)) // (11000000)
		{
			bUTF8 = false;
			break;
		}
		else if (*start < (0xE0)) // (11100000)
		{
			if (start >= end - 1)
				break;
			if ((start[1] & (0xC0)) != 0x80)
			{
				bUTF8 = false;
				break;
			}
			start += 2;
		}
		else if (*start < (0xF0)) // (11110000)
		{
			if (start >= end - 2)
				break;
			if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80)
			{
				bUTF8 = false;
				break;
			}
			start += 3;
		}
		else
		{
			bUTF8 = false;
			break;
		}
	}
	return bUTF8;
}

 

※ 친절하게 BOM이 존재하는 문서라면 명확하게 인코딩이 구분되지만 BOM이 없으면 파일의 코드를 분석해서 분석할 수 밖에 없습니다.

 

※ 위 방법은 대부분의 경우 BOM이 없는 UTF8을 구분할 수 있지만 완벽한 방법은 아니니 참고만 해주세요.

 

반응형

댓글