冉冉说
最近在使用WriteFile函数时发现,vc2008中unicode字符集下处理中文乱码的一些解决方法,归纳如下1. 写入的时候采用多字节char类型HANDLE hFile;DWORD nBytes;hFile=CreateFile(_T("test.txt"),GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,0,NULL);char msg[]="我是我的我";if(hFile!=INVALID_HANDLE_VALUE){WriteFile(hFile,msg, sizeof(msg) ,&nBytes,NULL);CloseHandle(hFile);}2. 直接写入unicode的头字节HANDLE hFile;DWORD nBytes;hFile=CreateFile(_T("test.out"),GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,0,NULL);WCHAR msg[]=L"我是我的我";if(hFile!=INVALID_HANDLE_VALUE){DWORD a=0xFEFF;WriteFile(hFile,&a,sizeof(a),&nBytes,NULL);WriteFile(hFile,msg, lstrlen(msg) * sizeof(TCHAR),&nBytes,NULL);//第三个参数可以直接sizeof(msg)CloseHandle(hFile);}3. 使用WideCharToMultiByte转换成多字节(省略)4. 使用wcstombs转换成多字节,需要引用wchar.h和locale.hHANDLE hFile;DWORD nBytes;hFile=CreateFile(_T("test.out"),GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,0,NULL);WCHAR msg[]=L"我是我的我";if(hFile!=INVALID_HANDLE_VALUE){char buf[sizeof(msg)];setlocale(LC_ALL, ".936");wcstombs(buf, msg, sizeof(msg));WriteFile(hFile,buf, sizeof(buf),&nBytes,NULL);CloseHandle(hFile);}//*********以下为读入***********************//hFile=CreateFile(_T("test.txt"),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,0,NULL);if(hFile!=INVALID_HANDLE_VALUE){WCHAR line[256]={0};BOOL bResult;bResult=ReadFile(hFile,line,sizeof(line),&nBytes,NULL);if(nBytes!=0){printf("%s\r\n",line);}CloseHandle(hFile);}
侃侃无极
因为你没有进行字符的转换,我们需要将buf进行转换。这就要用到了WideCharToMultiByte.如何用呢?首先我的方法比较笨,可以这么用的:char* pchBuffer = new char[dwLen+1];WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, pchBuffer, dwLen+1, NULL, FALSE );WriteFile(hFile, pBuffer, dwLen+1, &dwSize, NULL );Delete[] pchBuffer;此时注意,我在WriteFile中用了dwLen+1。结果就是在文件的末尾出现了乱码,正好多一个乱码出来。所以WriteFile中nNumberOfBytesToWrite是写的字符串的数目,是不包括’\0’的。此时注意,我在WriteFile中用了dwLen+1。结果就是在文件的末尾出现了乱码,正好多一个乱码出来。所以WriteFile中nNumberOfBytesToWrite是写的字符串的数目,是不包括’\0’的。这个方法笨,是因为我们的函数可以缩减为两个参数。是因为如下这么写时,dwLen是所要转换的字符串的个数,此时转换的字符串是包括’\0’的。DWORD dwLen = WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, NULL, NULL, NULL, FALSE );