使用 WideCharToMultiByte 个别字符出现乱码

生命沉思者 2011-03-10 09:07:53

最近利用代码读取NTFS磁盘的文件名时,发现读出的文件名大部分正常,但少部分会出现乱码,如:

越玩越聪明全集-全世界聪明人都在玩的1001个全脑思维游戏.pdf 变成
越玩越聪明全$-全世界聪明人都在玩的1001个全脑思维游戏.pdf


身体语言:从他人的身体姿势了解其内心世界.pdf 变成
身体语言:从他人的身体姿势了解其内心世界.p$f


请问这是什么原因呢,下面的代码



int len = buffer[off_index + 80]; //文件名长度,unsigned char buffer[4096];unsigned int off_index

WCHAR* name_unicode = new WCHAR[len + 1];
for (int i = 0; i < len; i++)
name_unicode[i] = buffer[off_index + 82 + 2 * i] + buffer[off_index + 82 + 2 * i + 1] * 256;

name_unicode[len] = NULL;
DWORD dwNum = 0;




char* psText;
psText = new char[dwNum + 1];
WideCharToMultiByte(CP_OEMCP , NULL, name_unicode, -1, psText, dwNum, NULL, FALSE);
psText[dwNum ] = '\0';

MessageBox(NULL,psText,psText,MB_OK); <-----------------乱码从这里看出来
CString f;
f.Format("%s", psText);

delete []psText;
delete []name_unicode;

...全文
621 11 打赏 收藏 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuyueguang 2012-10-13
  • 打赏
  • 举报
回复
6楼这个就可以啊
[Quote=引用 6 楼 的回复:]

C/C++ code

wchar_t szText[] = L"越玩越聪明全集-全世界聪明人都在玩的1001个全脑思维游戏.pdf";
char* buf = NULL;
int len = WideCharToMultiByte(CP_ACP, 0, szText, -1, buf, 0, NULL, NULL);
buf = new char[len];
……
[/Quote]
Yofoo 2011-03-13
  • 打赏
  • 举报
回复
ntfs磁盘扇区的数据需要把USN数据重写回去, 否则每个扇区将会有2个字节的数据错误


typedef struct _MFT_FILE_HEADER
{
union
{
DWORD dwMagic; //00 "FILE"
CHAR szMagic[4];
};

WORD wOffsetOfUS; //04 Offset of Update Sequence 更新序列号的偏移
WORD wSizeOfUS; //06 Size in words of Update Sequence Number & Array 更新序列号的大小与数组
ULONGLONG uuLSN; //08 $LogFile Sequence Number 日志文件序列号
WORD wSeqNo; //10 Sequence number The increment is done when the file is deleted.
WORD wHardlinks; //12 Hard link count 硬连接数,即有多少目录指向该文件
WORD wOffsetOfAttr; //14 Offset of the first Attribute 第一个属性的偏移
WORD wFlags; //16 Flags 文件被删除后FLAG=0
DWORD dwRealSize; //18 Real size of the FILE record 这个文件记录中已用的大小
DWORD dwAllocSize; //1C Allocated size of the FILE record
ULONGLONG uuRefToBase; //20 File reference to the base FILE record 基本文件记录中的文件索引号
WORD wNextAttrId; //28 Next Attribute Id 下一属性ID
WORD wAlign; //2A Align to 4 byte boundary
DWORD dwRecordNo; //2C Number of this MFT Record
}MFT_FILE_HEADER; // size:0x30




BOOL CNtfsMFT::ReadMft(CHAR cVolume, ULONGLONG uuMftIndex)
{
BOOL bRetVal;
DWORD dwSectors;
WORD wUSNCheck;
WORD * pUSNTable;

AllocMftHead(cVolume);

bRetVal = m_pDiMgr->ReadMtf(cVolume, uuMftIndex, m_pHead);
if(bRetVal == FALSE)
{
assert(0);
return FALSE;
}
m_uuMftIndex = uuMftIndex;

dwSectors = m_pCurVolume->m_dwBytePreMtf / m_pCurVolume->m_BootDat.NtfsBoot.BytesPerSector;
pUSNTable = (WORD*)((BYTE*)m_pHead + m_pHead->wOffsetOfUS);
wUSNCheck = *pUSNTable;
pUSNTable ++;

bRetVal = UpdateByUSN(m_pHead, dwSectors, wUSNCheck, pUSNTable);
if(bRetVal == FALSE)
{
assert(0);
return FALSE;
}

return bRetVal;
}

BOOL CNtfsMFT::UpdateByUSN(VOID *pData, DWORD dwSectors, WORD wUSNCheck, WORD *pUSNTable)
{
BYTE * pDatWrite;
DWORD i;
DWORD dwSectorSize;

dwSectorSize = m_pCurVolume->m_BootDat.NtfsBoot.BytesPerSector;
pDatWrite = (BYTE *)pData;

pDatWrite += dwSectorSize - 2;
for(i=0; i<dwSectors; i++)
{
if(*(WORD *)pDatWrite != wUSNCheck)
{
assert(0);
return FALSE;
}

*(WORD *)pDatWrite = pUSNTable[i];
pDatWrite += dwSectorSize;
}

return TRUE;
}

生命沉思者 2011-03-13
  • 打赏
  • 举报
回复
没有哪位老大知道吗?自己顶上去
生命沉思者 2011-03-12
  • 打赏
  • 举报
回复
没有哪位老大知道吗?自己顶上去
生命沉思者 2011-03-11
  • 打赏
  • 举报
回复
中间是少了一句,不好意思,复制时漏了

DWORD dwNum = 0;
dwNum = WideCharToMultiByte(CP_OEMCP, NULL, name_unicode, -1, NULL, 0, NULL, FALSE); //该函数映射一个unicode字符串到一个多字节字符串
psText = new char[dwNum + 1];

我改成CP_ACP还是不行
生命沉思者 2011-03-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jennyvenus 的回复:]
for (int i = 0; i < len; i++)
name_unicode[i] = buffer[off_index + 82 + 2 * i] + buffer[off_index + 82 + 2 * i + 1] * 256;

---------------
多此一举了吧。
[/Quote]

这并非多此一举,这代码是从磁盘上读出NTFS的文件名
Eleven 2011-03-11
  • 打赏
  • 举报
回复

wchar_t szText[] = L"越玩越聪明全集-全世界聪明人都在玩的1001个全脑思维游戏.pdf";
char* buf = NULL;
int len = WideCharToMultiByte(CP_ACP, 0, szText, -1, buf, 0, NULL, NULL);
buf = new char[len];
WideCharToMultiByte(CP_ACP, 0, szText, -1, buf, len, NULL, NULL);
AfxMessageBox(CString(buf));
delete[] buf;
buf = NULL;
wliaoc 2011-03-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jennyvenus 的回复:]
for (int i = 0; i < len; i++)
name_unicode[i] = buffer[off_index + 82 + 2 * i] + buffer[off_index + 82 + 2 * i + 1] * 256;

---------------
多此一举了吧。
[/Quote]
从出错的位置来看,好像就是一个汉字两个字节,字符一个字节的位置出错的。
所以我支持这种看法
用户 昵称 2011-03-11
  • 打赏
  • 举报
回复
for (int i = 0; i < len; i++)
name_unicode[i] = buffer[off_index + 82 + 2 * i] + buffer[off_index + 82 + 2 * i + 1] * 256;

---------------
多此一举了吧。
aiwnx 2011-03-10
  • 打赏
  • 举报
回复
同意楼上的意见,如果是中文操作系统的话,试试CP_ACP ?
youngwolf 2011-03-10
  • 打赏
  • 举报
回复
代码不全吧?
DWORD dwNum = 0;
psText = new char[dwNum + 1];

估计是CP_OEMCP参数的问题,你用ATL的A2T试试。

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧