C++ unicode2ansi 字符串转化(新人发帖,大神笔下留情)

tingtings324 2015-05-29 02:55:18
最近做的一个项目,功能涉及包含 英文音标 的字符串转化,需要从unicode 转化到ansi编码,当然自己也试过惯用转化函数 WideCharToMultiByte,结果发现英文音标里面的特殊字符类似ɔ:ʌə之类都用代替。之后也试过iconv库的转化,发现效果不佳。然后查好多资料,有人说 “因为英语音标系统需要一些ascii字符以外的符号,这些符号在Unicode出现前没有统一的编码和相应的字体,需要用特殊字体实现。所以在音标的输入和显示上造成了一定的混乱。”万般无奈,广发英雄帖,求大神相助。
...全文
944 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
tingtings324 2015-06-11
  • 打赏
  • 举报
回复
引用 31 楼 tajon1226 的回复:
"不过之前那个前辈buff里面存放的是一个流文件,不像从文本读取这么简单" 恩,目前能证明CRichEdit 2.0版本可以显示Unicode字符,起码有一点,功能实现变简单了。 不然Unicode转多字节,这条路更麻烦。 那些用多字节显示音标的,估计都是自己编的字体库。
嗯,新建Unicode文件弄好了,但是...你那个读取是怎么做到的,我这边死活用LPBYTE接收不到正常的字符串呀。感觉没道理
tingtings324 2015-06-11
  • 打赏
  • 举报
回复
引用 31 楼 tajon1226 的回复:
"不过之前那个前辈buff里面存放的是一个流文件,不像从文本读取这么简单" 恩,目前能证明CRichEdit 2.0版本可以显示Unicode字符,起码有一点,功能实现变简单了。 不然Unicode转多字节,这条路更麻烦。 那些用多字节显示音标的,估计都是自己编的字体库。
诶?有没有可能代码新建一个Unicode编码的TXT文件呢啊。我试了许久,貌似都找不到...
走好每一步 2015-06-10
  • 打赏
  • 举报
回复
"不过之前那个前辈buff里面存放的是一个流文件,不像从文本读取这么简单" 恩,目前能证明CRichEdit 2.0版本可以显示Unicode字符,起码有一点,功能实现变简单了。 不然Unicode转多字节,这条路更麻烦。 那些用多字节显示音标的,估计都是自己编的字体库。
tingtings324 2015-06-10
  • 打赏
  • 举报
回复
引用 28 楼 tajon1226 的回复:
调用PaperIn函数可以把Unicode格式的txt文本信息显示到CRichEdit上。 没有再出现乱码了 PaperIn(L"in.txt"); 这是in.txt的内容:开合双元音 [ei] [ai] [ɔi] [əu]
那么,现在又回到初始的状态,怎么样能把获取到的CString 字符串,转化到回调函数的buff里面,那么问题就ok了,你恍然大悟了吧。哈哈
tingtings324 2015-06-10
  • 打赏
  • 举报
回复
引用 28 楼 tajon1226 的回复:
调用PaperIn函数可以把Unicode格式的txt文本信息显示到CRichEdit上。 没有再出现乱码了 PaperIn(L"in.txt"); 这是in.txt的内容:开合双元音 [ei] [ai] [ɔi] [əu]
嗯,你再仔细点就能发现,PaperIn函数里面还是调用了richedit.streamin,不过我惊奇的是,es的回调函数,里面那个buff居然能存放特殊音标字符。嗯,看来我还是哪块没有处理好,不过之前那个前辈buff里面存放的是一个流文件,不像从文本读取这么简单,里面除了要显示的信息之外,还用其他标签保存了一些配置信息,比如文本怎么分行,字体大小什么的。嗯容我再悟悟,多谢多谢!
走好每一步 2015-06-09
  • 打赏
  • 举报
回复
考虑自绘控件吧。 我试过了。 streamin这个函数调用的是windows的API函数 具体它里面是怎么实现的,估计只有windows的设计者才知道了。
tingtings324 2015-06-09
  • 打赏
  • 举报
回复
引用 24 楼 tajon1226 的回复:
考虑自绘控件吧。 我试过了。 streamin这个函数调用的是windows的API函数 具体它里面是怎么实现的,估计只有windows的设计者才知道了。
嗯,大概是根据那个回调函数的流文件里面的具体信息来确定文字在编辑框内的大小还有位置。所以,一开题我就问了一下,那个转换。现在看来是不太好转换了,再问一下,这个分怎么给,毕竟你也辛苦看这么久了。对吧。哈哈。第一次发帖见谅
走好每一步 2015-06-09
  • 打赏
  • 举报
回复
调用PaperIn函数可以把Unicode格式的txt文本信息显示到CRichEdit上。 没有再出现乱码了 PaperIn(L"in.txt"); 这是in.txt的内容:开合双元音 [ei] [ai] [ɔi] [əu]
走好每一步 2015-06-09
  • 打赏
  • 举报
回复
http://www.94cto.com/index/Article/content/id/113.html 这篇文章讲的比较全面,可以看一下。 自绘控件没那么简单的。 我根据文章找到解决方法了。 可以在RichEdit控件里显示Unicode文字了。
BOOL CPhoneticSymbolDlg::PaperIn(CString PathName)
{
	CFile cFile(PathName, CFile::modeRead);
	EDITSTREAM es;

	es.dwCookie = (DWORD) &cFile;
	es.pfnCallback = MyStreamInCallback; 
	richEd.StreamIn(SF_TEXT | SF_UNICODE, es);

	return TRUE;
}

DWORD CALLBACK CPhoneticSymbolDlg::MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	CFile* pFile = (CFile*) dwCookie;

	*pcb = pFile->Read(pbBuff, cb);
	return 0;
}

BOOL CPhoneticSymbolDlg::PaperOut(CString PathName)
{
	CFile cFile(PathName, CFile::modeCreate|CFile::modeWrite);
	EDITSTREAM es;

	es.dwCookie = (DWORD) &cFile;
	es.pfnCallback = MyStreamOutCallback; 
	richEd.StreamOut(SF_UNICODE | SF_TEXT, es);
	return TRUE;
}

DWORD CALLBACK CPhoneticSymbolDlg::MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	CFile* pFile = (CFile*) dwCookie;

	pFile->Write(pbBuff, cb);
	*pcb = cb;

	return 0;
}
tingtings324 2015-06-09
  • 打赏
  • 举报
回复
引用 24 楼 tajon1226 的回复:
考虑自绘控件吧。 我试过了。 streamin这个函数调用的是windows的API函数 具体它里面是怎么实现的,估计只有windows的设计者才知道了。
蓦然,再一想,你是想叫我重写控件自绘的streamin函数,直接把tchar传进去然后绘制在对应位置,诶呀我的个脑子,嗯这起码是个办法,谢谢谢谢!!!
tingtings324 2015-06-08
  • 打赏
  • 举报
回复
引用 22 楼 tajon1226 的回复:
我用的是VS2008 Unicode编译环境 1 DC显示音标没问题 2 控件显示也没问题,只是把默认字体改成宋体就可以了
else
	{
		CDialog::OnPaint();
		CClientDC dc(this);
		wchar_t ch[] = _T("[iə][εə] [uə]");
		CFont font;
		VERIFY(font.CreateFont(
			12,                        // nHeight
			0,                         // nWidth
			0,                         // nEscapement
			0,                         // nOrientation
			FW_NORMAL,                 // nWeight
			FALSE,                     // bItalic
			FALSE,                     // bUnderline
			0,                         // cStrikeOut
			ANSI_CHARSET,              // nCharSet
			OUT_DEFAULT_PRECIS,        // nOutPrecision
			CLIP_DEFAULT_PRECIS,       // nClipPrecision
			DEFAULT_QUALITY,           // nQuality
			DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
			_T("Arial")));                 // lpszFacename

		CFont* def_font = dc.SelectObject(&font);
		dc.TextOut(5, 5, ch, lstrlen(ch));
		dc.SelectObject(def_font);

		// Done with the font.  Delete the font object.
		font.DeleteObject(); 

		SetDlgItemText(IDC_RICHEDIT21, ch);
	}
你能用控件的streamin函数试试吗?SetDlgItemText根本就满足不了呀,因为涉及好多字体大小,还有位置信息
走好每一步 2015-06-06
  • 打赏
  • 举报
回复
我用的是VS2008 Unicode编译环境 1 DC显示音标没问题 2 控件显示也没问题,只是把默认字体改成宋体就可以了
else
	{
		CDialog::OnPaint();
		CClientDC dc(this);
		wchar_t ch[] = _T("[iə][εə] [uə]");
		CFont font;
		VERIFY(font.CreateFont(
			12,                        // nHeight
			0,                         // nWidth
			0,                         // nEscapement
			0,                         // nOrientation
			FW_NORMAL,                 // nWeight
			FALSE,                     // bItalic
			FALSE,                     // bUnderline
			0,                         // cStrikeOut
			ANSI_CHARSET,              // nCharSet
			OUT_DEFAULT_PRECIS,        // nOutPrecision
			CLIP_DEFAULT_PRECIS,       // nClipPrecision
			DEFAULT_QUALITY,           // nQuality
			DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
			_T("Arial")));                 // lpszFacename

		CFont* def_font = dc.SelectObject(&font);
		dc.TextOut(5, 5, ch, lstrlen(ch));
		dc.SelectObject(def_font);

		// Done with the font.  Delete the font object.
		font.DeleteObject(); 

		SetDlgItemText(IDC_RICHEDIT21, ch);
	}
走好每一步 2015-06-06
  • 打赏
  • 举报
回复
本来打了好多字,被CSDN坑了,没保存到。 楼主还是没开窍!没明白什么是Unicode和多字节。 把你重要的函数接口 贴出来 看看吧。 1.音标输入的接口 2.音标显示的接口 3.确认下你的编译环境到底是多字节还是Unicode?不懂可以百度。
走好每一步 2015-06-04
  • 打赏
  • 举报
回复
直接说的你要实现什么样的功能吧。 不要老说Unicode转多字节码。 就好比南辕北辙,我车好,马快。
tingtings324 2015-06-04
  • 打赏
  • 举报
回复
引用 19 楼 tajon1226 的回复:
还是不明白楼主所说,我先猜下楼主是不是想这样。 unicode->多字节->处理一些字符的处理->再转Unicode-显示。 1.只能自己写个转换函数 普通字符-》WideCharToMultiByte 特殊字符-》自己弄个不常用的编码对应过去 2.解释函数 普通字符-》MultiByte- 特殊字符-》编码对应音标的Unicode编码
你终于明白我的苦心了!但是!他的普通字符和特殊字符能用同一个吗因为是在同一个流文件里面!大大可以看一下richedit的streamin函数。如果不行,这个编码要怎么搞呀,因为这个是之前一个前辈的代码,然后父类子类好几层,我就是想在他输入汉字的时候能给他弄个拼音出来,输入英文句子的时候,显示英文音标出来。现在的话,拼音ok了,音标的话,实在搞不对。
tingtings324 2015-06-04
  • 打赏
  • 举报
回复
引用 14 楼 tajon1226 的回复:
直接说的你要实现什么样的功能吧。 不要老说Unicode转多字节码。 就好比南辕北辙,我车好,马快。
嗯,我用vs2010,功能的话是这样的,首先从对话框的客户区内选中一个英文的句子(当然这个选中也做过一些矩阵变换处理),这个时候算是设定的一个对象不可编辑状态,对这个选中的对象有个右键音标查找的功能,查找完之后,把音标和英文句子显示在一个重写过的richedit的控件内,这个时候算是可编辑状态,然后把控件内的内容绘制在相应的客户区,即可编辑状态又回到不可编辑。然后客户区的绘制是unicode,控件因为需要记录文字位置等一些信息,用到函数streamin流文件传输,这么说,不知道明白了吗
走好每一步 2015-06-04
  • 打赏
  • 举报
回复
还是不明白楼主所说,我先猜下楼主是不是想这样。 unicode->多字节->处理一些字符的处理->再转Unicode-显示。 1.只能自己写个转换函数 普通字符-》WideCharToMultiByte 特殊字符-》自己弄个不常用的编码对应过去 2.解释函数 普通字符-》MultiByte- 特殊字符-》编码对应音标的Unicode编码
赵4老师 2015-06-04
  • 打赏
  • 举报
回复
也许只是转化没失败,只是你无法用一种字体显示出所有Unicode字符罢了。 GetGlyphIndices The GetGlyphIndices function translates a string into an array of glyph indices. The function can be used to determine whether a glyph exists in a font. WINGDIAPI DWORD WINAPI GetGlyphIndices( HDC hdc, // device context LPCTSTR lpstr, // string to convert int c, // number of characters in string LPWORD pgi, // array of glyph indices DWORD fl // flags ); Parameters hdc Handle to the device context lpstr Pointer to the string to be converted. c Number of characters in pgi. pgi Array of glyph indices corresponding to the characters in the string. fl Flags indicating how glyphs should be handled if they are not supported. This parameter can be the following value: Value Meaning GGI_MARK_NONEXISTING_GLYPHS Mark unsupported glyphs with the hexadecimal value 0xffff. Return Values If the function succeeds, it returns the number of characters converted. If the function fails, the return value is GDI_ERROR. Windows NT: To get extended error information, callGetLastError. QuickInfo Windows NT: Requires version 5.0 or later. Windows: Unsupported. Windows CE: Unsupported. Header: Declared in wingdi.h. Import Library: Use gdi32.lib. See Also Fonts and Text Overview, Font and Text Functions, GetFontUnicodeRanges
tingtings324 2015-06-04
  • 打赏
  • 举报
回复
引用 16 楼 zhao4zhong1 的回复:
楼主怎么还没开悟呢? 基本上其它文字和音标文字用同一种字体同时显示是没戏的。
得,我再复制粘贴下,这个东西的流程是:首先从对话框的客户区内选中一个英文的句子(当然这个选中也做过一些矩阵变换处理),这个时候算是设定的一个对象不可编辑状态,对这个选中的对象有个右键音标查找的功能,查找完之后,把音标和英文句子显示在一个重写过的richedit的控件内,这个时候算是可编辑状态,然后把控件内的内容绘制在相应的客户区,即可编辑状态又回到不可编辑。然后客户区的绘制是unicode,控件因为需要记录文字位置等一些信息,用到函数streamin流文件传输,这么说,不知道明白了吗.所以,现在的重点不在于用哪种字体绘制,在于怎么样先转过去,现在转化的都是失败的,显示肯定是有问题的吧:小弟愚见,万望不吝赐教
赵4老师 2015-06-04
  • 打赏
  • 举报
回复
楼主怎么还没开悟呢? 基本上其它文字和音标文字用同一种字体同时显示是没戏的。
加载更多回复(13)
DirectX修复工具(DirectX Repair)是一款系统级工具软件,简便易用。本程序为绿色版,无需安装,可直接运行。 本程序的主要功能是检测当前系统的DirectX状态,如果发现异常则进行修复。程序主要针对0xc000007b问题设计,可以完美修复该问题。本程序中包含了最新版的DirectX redist(Jun2010),并且全部DX文件都有Microsoft的数字签名,安全放心。 本程序为了应对一般电脑用户的使用,采用了傻瓜式一键设计,只要点击主界面上的“检测并修复”按钮,程序就会自动完成校验、检测、下载、修复以及注册的全部功能,无需用户的介入,大大降低了使用难度。 本程序适用于多个操作系统,如Windows XP(需先安装.NET 2.0,详情请参阅“致Windows XP用户.txt”文件)、Windows Vista、Windows 7、Windows 8、Windows 8.1、Windows 8.1 Update、Windows 10,同时兼容32位操作系统和64位操作系统。本程序会根据系统的不同,自动调整任务模式,无需用户进行设置。 本程序的V3.3版分为标准版、增强版以及在线修复版。其中的标准版以及增强版都包含完整的DirectX组件。除此之外,增强版中还额外包含了c++ Redistributable Package,因此增强版不但能解决DirectX组件的问题,而且还能解决c++组件异常产生的问题。增强版适合无法自行解决c++相关问题的用户使用。在线修复版的功能与标准版相同,只是其所需的文件将通过Internet下载,因此大大减小了程序的体积。本程序的各个版本之间,主程序完全相同,只是配套使用的数据包不同。因此,当您使用标准版数据包时,程序将进行标准修复;当您使用增强版的数据包时,程序将进行增强修复;当数据包不全或没有数据包(即只有DirectX Repair.exe程序)时,程序将进行在线修复。在线修复、离线修复可自由灵活组合,充分满足不同用户的需要。 本程序自V2.0版起采用全新的底层程序架构,使用了异步多线程编程技术,使得检测、下载、修复单独进行,互不干扰,快速如飞。新程序更改了自我校验方式,因此使用新版本的程序时不会再出现自我校验失败的错误;但并非取消自我校验,因此程序安全性与之前版本相同,并未降低。 程序有自动更新c++功能。由于绝大多数软件运行时需要c++的支持,并且c++的异常也会导致0xc000007b错误,因此程序在检测修复的同时,也会根据需要更新系统中的c++组件。自V3.2版本开始使用了全新的c++扩展包,可以大幅提高工业软件修复成功的概率。修复c++的功能仅限于增强版,标准版及在线修复版在系统c++异常时(非丢失时)会提示用户使用增强版进行修复。 程序有两种窗口样式。正常模式即默认样式,适合绝大多数用户使用。另有一种简约模式,此时窗口将只显示最基本的内容,修复会自动进行,修复完成10秒钟后会自动退出。该窗口样式可以使修复工作变得更加简单快速,同时方便其他软件、游戏将本程序内嵌,即可进行无需人工参与的快速修复。开启简约模式的方法是:打开程序所在目录下的“Settings.ini”文件(如果没有可以自己创建),将其中的“FormStyle”一项的值改为“Simple”并保存即可。 程序有高级筛选功能,开启该功能后用户可以自主选择要修复的文件,避免了其他不必要的修复工作。同时,也支持通过文件进行辅助筛选,只要在程序目录下建立“Filter.dat”文件,其中的每一行写一个需要修复文件的序号即可。该功能仅针对高级用户使用,并且必须在正常窗口模式下才有效(简约模式时无效)。 本程序有自动记录日志功能,可以记录每一次检测修复结果,方便在出现问题时,及时分析和查找原因,以便找到解决办法。 程序的“选项”对话框中包含了4项高级功能。点击其中的“注册系统文件夹中所有dll文件”按钮可以自动注册系统文件夹下的所有dll文件。该项功能不仅能修复DirectX的问题,还可以修复系统中很多其他由于dll未注册而产生的问题,颇为实用。点击该按钮旁边的小箭头,还可以注册任意指定文件夹下的dll文件,方便用户对绿色版、硬盘版的程序组件进行注册。点击第二个按钮可以为dll文件的右键菜单添加“注册”和“卸载”项,方便对单独的dll文件进行注册。请注意,并不是所有的dll文件都可以通过这种方式注册。点击“DirectX版本”选项卡可以自行修改系统中DirectX的版本信息。点击“DirectX加速”选项卡可以控制系统中DirectX加速的开启与关闭。 新版程序集成了用户反馈程序,可以在用户允许的前提下发送检测修复结果。用户也可以在出现问题时通过反馈程序和软件作者进行交流,共同查找问题。反馈是完全自愿和匿名(如果不填写E-mail地址)的。 本程序的通用版基于Microsoft .NET Framework 2.0开发,对于Windows 2000、Windows XP、Windows 2003的用户需要首先安装.NET Framework 2.0或更高版本方可运行本程序。有关下载和安装的详细信息请参阅“致Windows XP用户.txt”文件。对于Windows Vista、Windows 7及后续用户,可以直接运行本程序。 同时鉴于Windows 8(Windows 8.1、Windows 8.1 Update)、Windows 10系统中默认未包含.NET Framework 2.0,因此新版的程序文件夹内将包含一个DirectX_Repair_win8的特别版程序,该程序功能与通用版相同,基于.NET Framework 4.0开发,可以在Windows8(Windows 8.1、Windows 8.1 Update)、Windows 10系统中直接运行(其他系统如果安装了.NET Framework 4.0也可以运行这个特别版的程序)。 本程序的官方博客地址为:http://blog.csdn.net/vbcom/article/details/6962388 所有的更新以及技术支持都可以到该博客上找到。

65,207

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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