#define STRICT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif
#define DEFAULT_BUFF_LEN 512
int Utf16ToUtf8(char *dest, size_t dest_size, wchar_t *src, size_t src_size);
int main(int argc, char *argv[])
{
wchar_t instr[DEFAULT_BUFF_LEN];
char outstr[DEFAULT_BUFF_LEN];
FILE *pFile;
long sizeFile = 0;
size_t countRead;
int instr_size = 0;
int iResult = 0;
char *pOutStr = NULL;
memset(instr, 0, sizeof(instr));
pFile = fopen("data.txt", "rb");
if (pFile == NULL)
{
perror("ファイルがひらけません: data.txt");
return 1;
}
fseek(pFile, 0, SEEK_END);
sizeFile = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
countRead = fread(instr, min(sizeFile, DEFAULT_BUFF_LEN), 1, pFile);
fclose(pFile);
if (countRead == 0)
{
perror("ファイル読み込み失敗: data.txt");
return 1;
}
instr_size = min(sizeFile, DEFAULT_BUFF_LEN) * countRead / sizeof(wchar_t);
memset(outstr, 0, sizeof(outstr));
iResult = Utf16ToUtf8(outstr, sizeof(outstr), instr, instr_size);
if (iResult == FALSE)
{
perror("Utf16ToUtf8() Failed.\n");
return 1;
}
printf("%d バイト変換しました。\n", iResult);
pOutStr = outstr;
if ((*pOutStr == '\xef') && (*(pOutStr + 1) == '\xbb')
&& (*(pOutStr + 2) == '\xbf'))
{
pOutStr += 3;
iResult -= 3;
}
pFile = fopen("out.txt", "wb");
if (pFile == NULL)
{
perror("ファイルが開けません: out.txt");
return 1;
}
fwrite(pOutStr, iResult, 1, pFile);
fclose(pFile);
return 0;
}
int Utf16ToUtf8(char *dest, size_t dest_size, wchar_t *src, size_t src_size)
{
wchar_t bom;
long countNeedsBytes;
long cursor;
wchar_t wcWork1;
long sizeBytes;
char chWork1;
char chWork2;
char chWork3;
if (dest_size == 0)
{
}
else
{
if (dest == NULL)
{
return FALSE;
}
if (dest_size < 0)
{
return FALSE;
}
}
if (src == NULL)
{
return FALSE;
}
if (src_size < 0)
{
return FALSE;
}
countNeedsBytes = 0;
for (cursor = 0; cursor < src_size; cursor++)
{
wcWork1 = *(src + cursor);
if ( (wcWork1 <= ((wchar_t)0x007f)))
{
sizeBytes = 1;
}
else if ( (((wchar_t)0x0080) <= wcWork1)
&& (wcWork1 <= ((wchar_t)0x07ff)))
{
sizeBytes = 2;
}
else if ( (((wchar_t)0x0800) <= wcWork1))
{
sizeBytes = 3;
}
else
{
return FALSE;
}
if (dest_size && (dest_size < (countNeedsBytes + sizeBytes)))
{
return countNeedsBytes;
}
if (dest_size) switch (sizeBytes)
{
case 1:
*dest = (char)wcWork1;
dest ++;
break;
case 2:
chWork1 = (char)(wcWork1 >> 6);
chWork1 |= (char)0xc0;
chWork2 = (char)wcWork1;
chWork2 &= (char)0x3f;
chWork2 |= (char)0x80;
*dest = chWork1;
dest++;
*dest = chWork2;
dest++;
break;
case 3:
chWork1 = (char)(wcWork1 >> 12);
chWork1 &= (char)0x0f;
chWork1 |= (char)0xe0;
chWork2 = (char)(wcWork1 >> 6);
chWork2 &= (char)0x3f;
chWork2 |= (char)0x80;
chWork3 = (char)wcWork1;
chWork3 &= (char)0x3f;
chWork3 |= (char)0x80;
*dest = chWork1;
dest++;
*dest = chWork2;
dest++;
*dest = chWork3;
dest++;
break;
default:
break;
}
countNeedsBytes += sizeBytes;
}
return countNeedsBytes;
}
|