Ⅰ 如何在linux系统实现字符编码转换
Linux下提供了iconv实现这一功能,在Linux
的
shell
环境下,iconv用法如下:
iconv
-f
fromconde
-t
tocode
-f:
指定需要转换的文本编码
-t:
指定目标文本编码
我们也可以用
-l
列举出所有已知的字符编码集合
iconv
-l
具体用法可以通过帮助函数
iconv
--help来详细了解
另外,我们也可以在程序中直接使用该函数实现文本的编码转换
#ifndef
__CODE_CONVERTER
#define
__CODE_CONVERTER
#ifdef
WIN32
#include
<windows.h>
#else
#include
<iconv.h>
#endif
class
CodeConverter
{
private:
#ifndef
WIN32
iconv_t
m_cd;
#endif
const
char*
m_pszFromCode;
const
char*
m_pszToCode;
public:
CodeConverter()
{
m_pszFromCode
=
NULL;
m_pszToCode
=
NULL;
#ifndef
WIN32
m_cd
=
0;
#endif
}
~CodeConverter()
{
#ifndef
WIN32
iconv_close(m_cd);
#endif
}
bool
Initialize(const
char
*pszToCode,
const
char
*pszFromCode);
size_t
Convert(char*
inBuf,
size_t
inBytesLeft,
char*
outBuf,
size_t
outBytesLen);
};
#endif
#include
<string.h>
#include
<stdlib.h>
#include
<stdio.h>
#include
"code_converter.h"
#include
<errno.h>
bool
CodeConverter::Initialize(const
char*
pszToCode,
const
char*
pszFromCode)
{
if(pszFromCode
==
NULL
||
pszToCode
==
NULL)
return
false;
m_pszFromCode
=
pszFromCode;
m_pszToCode
=
pszToCode;
#ifndef
WIN32
m_cd
=
iconv_open(m_pszToCode,m_pszFromCode);
if(m_cd
==
(iconv_t)-1)
{
printf("cannot
open
iconv
descripter\n");
return
false;
}
#endif
return
true;
}
size_t
CodeConverter::
Convert(char*
inBuf,
size_t
inBytesLeft,
char*
outBuf,
size_t
outBytesLen)
{
int
nRealLen
=
0;
#ifdef
WIN32
if(stricmp(m_pszFromCode,"UNICODE")
==
0)
{
nRealLen
=
WideCharToMultiByte(CP_ACP,0,(PWCHAR)inBuf,
inBytesLeft,
(PCHAR)outBuf,
outBytesLen,NULL,NULL);
}
if(stricmp(m_pszFromCode,"gb2312")
==
0)
{
nRealLen
=
MultiByteToWideChar(CP_ACP,0,(PCHAR)inBuf,inBytesLeft,(PWCHAR)outBuf,
outBytesLen);
}
#else
size_t
outBytesLeft
=
outBytesLen;
size_t
ret
=
0;
while
(1)
{
ret
=
iconv(m_cd,
&inBuf,
&inBytesLeft,
&outBuf,
&outBytesLeft);
if
(ret
==
0)
break;
if
(ret
==
(size_t)-1)
{
printf("iconv
error
aaa:
%s\n",strerror(errno));
return
-1;
}
inBuf++;
inBytesLeft--;
}
nRealLen
=
outBytesLen-outBytesLeft;
outBuf[nRealLen]=0;
#endif
return
nRealLen;
}
Ⅱ 用MultiByteToWideChar将char转换为wchar就代表将ansi转换为utf-8了吗那在linux下用wcstombs转回来
在linux下用iconv
Ⅲ Linux下宽字符串输出问题,求解...
setlocale( LC_ALL, "chs " );
看看是不是没有调用这个函数
for example
char str[1024] = "abc123故障短路切换";
wchar_t array[1024]={0};
setlocale(LC_ALL,"zh_CN.GB2312");
/*from chinese to Unicode*/
if((ret=mbstowcs(array, str, strlen(str)))==-1)
{
printf("error\n");
}
goodluck
Ⅳ Linux下LPCWSTR与BSTR区别
字符串转换_BSTR/LPSTR/LPWSTR/Char
一、BSTR、LPSTR和LPWSTR
在Visual C++.NET的所有编程方式中,我们常常要用到这样的一些基本字符串类型,如BSTR、LPSTR和LPWSTR等。之所以出现类似上述的这些数据类型,是因为不同编程语言之间的数据交换以及对ANSI、Unicode和多字节字符集(MBCS)的支持。
那么什么是BSTR、LPSTR以及LPWSTR呢?
BSTR(Basic STRing,Basic字符串)是一个OLECHAR*类型的Unicode字符串。它被描述成一个与自动化相兼容的类型。由于操作系统提供相应的API函数(如SysAllocString)来管理它以及一些默认的调度代码,因此BSTR实际上就是一个COM字符串,但它却在自动化技术以外的多种场合下得到广泛使用。图1描述了BSTR的结构,其中DWORD值是字符串中实际所占用的字节数,且它的值是字符串中Unicode字符的两倍。
LPSTR和LPWSTR是Win32和VC++所使用的一种字符串数据类型。LPSTR被定义成是一个指向以NULL(‘\0’)结尾的8位ANSI字符数组指针,而LPWSTR是一个指向以NULL结尾的16位双字节字符数组指针。在VC++中,还有类似的字符串类型,如LPTSTR、LPCTSTR等
Ⅳ 有宏 -t 就属于windows编程吗windows编程的入口函数也可以是 -tmain()吗
_t 或 _T 这样的前缀或后缀在有些情况下并没有什么意义,如 size_t、uint_t 等。在有些情况下则只是一个宏,表示一个通用名称,这个名称在编译的时候才能确定,并不是 Windows 专用的。早期的 Windows 系统使用 ANSI 编码,在不同语言编码的系统上运行会出现乱码。而从 2000 开始,Windows 支持 ANSI 和 Unicode 编码,因此所有的与字符有关的 Windows API 均有两个不同的版本,如 SetWindowText 这个 API,事实上是不存在的,只有 SetWindowTextA(用于 char 类型)和 SetWindowTextW(用于 wchar_t 类型)。Linux 系统虽然也用 char 类型,但其 char 是 UTF-8 编码的,不会乱码,因此你很少看到 Linux 上使用 _t。但是 Linux 也有 char 和 wchar_t 数据类型,这点与 Windows 是一致的。即不管在哪个平台,C 语言中的字符类型都有 char 和 wchar_t 两种类型。如 _tprintf 这个宏,本身不是一个函数名,它可能被替换为代表 printf(用于 char 类型)或者 wprintf(用于 wchar_t 类型),取决于是否定义了 UNICODE。同样的 Windows 控制台程序的入口有 main 和 wmain,但是它被定义为 _tmain,这个宏在定义 Unicode 时等于 wmain,未定义是等于 main。Windows GUI 程序入口有 WinMain 和 wWinMain,它被定义为宏 _tWinMain。同样地,上面提到的 SetWindowText,当定义 UNICODE 时,SetWindowText 被定义为 SetWindowTextW,未定义时代表 SetWindowTextA。在 C 语言中,wchar_t 类型的宽字符在声明时,字符或字符串串前需要加 L 以便编译器知道这是宽字符。所以针对字符串也定义了宏 _T,其 Windows 版名称为 TEXT。_tprintf 和 _T 这样的宏都是 C 标准,定义在 tchar.h 中。现以一个简单的命令行程序说明一下这些宏的意义。假如有这样的代码:
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>
int _tmain(int argc, TCHAR *argv[])
{
TCHAR szText[] = TEXT("Sample string.");
_tprintf(TEXT("%s"), szText)
SetWindowText(GetDesktopWindow(), szText);
return 0;
}
定义 UNICODE 时,等同于:
int wmain(int argc, wchar_t *argv[])
{
wchar_t szText[] = L"Sample string.";
wprintf(L"%s", szText)
SetWindowTextW(GetDesktopWindow(), szText);
return 0;
}
未定义 UNICODE 时,等同于:
int main(int argc, char *argv[])
{
char szText[] = "Sample string.";
printf("%s", szText)
SetWindowTextA(GetDesktopWindow(), szText);
return 0;
}
不过 wmain、WinMain、wWinMain 这几个入口是 Windows 特有的。
Ⅵ 100财富给牛逼之人!就没人知道在linux下用c语言如何将汉字的unicode编码转化为汉字吗
除了iconv命令,我们在linux系统下的man page的第三节还可以看到一组iconv函数。它们分别是
iconv_t iconv_open(const char *tocode, const char *fromcode);
size_ticonv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
int iconv_close(iconv_t cd);
iconv_open函数用来打开一个编码转换的流,iconv函数的作用是实际进行转换,iconv_close函数的作用就是关闭这个流。实际用法参见下面的例子,下面是一个将UTF-8码转换成GBK码的例子,我们假设已经有了一个uft8编码的输入缓冲区inbuf以及这个缓冲区的长度inlen。
iconv_t cd = iconv_open( "GBK", "UTF-8");
char *outbuf = (char *)malloc(inlen * 4 );
bzero( outbuf, inlen * 4);
char *in = inbuf;
char *out = outbuf;
size_t outlen = inlen *4;
iconv(cd, &in, (size_t *)&inlen, &out,&outlen);
outlen = strlen(outbuf);
printf("%s\n",outbuf);
free(outbuf);
iconv_close(cd);
Ⅶ Linux下怎么将wchar
在<WCHAR.h>头文件中有定义
typedef unsigned short wchar_t;
就是 wide character type 的意思
在 美国资讯交换标准码(ASCII: American Standard Code for Information Interchange)
开发过程中 为了节约成本(排除8位, 当时每位元的存储空间成本很昂贵) 最终由美国国家标准协会发布了7位版本的方案 记录在ANSI X3.4-1986 中
该标准在美国及拉丁字母国家使用方便 但在远东 西欧南部 会遇到拉丁字母中不存在的字母
比如俄语(斯拉夫) 希腊语 希伯来语 阿拉伯语 以及 汉字 日语 韩语
为了解决的字符集不同的恶心问题(内码转换) 诞生了Unicode字符集 它比ASCII多了一倍空间
这个wchar_t 就是Unicode对应的资料结构 它是16位的 可以装得下汉字哦
wchar_t *p = L"ooxx!"; 这个L告诉编译器, 把字母扩展为宽字符
你也会见到 _T(ooxx) 或者 TEXT(之类的写法) 他们都是为了让你的代码能在美欧以外运行
#ifdef UNICODE //UNICODE版
#define __T(x) L##x //这##字符串连接符 你应该知道滴
#else //ASCII版
#define __T(x) (x)
#endif
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
因此他们都是一样的
在windows的编程中 更普遍的写法是用WCHAR取代wchar_t
因为符合微软的命名规则 当然你如果喜欢Linux的话...
typedef char CHAR
typedef wchar_t WCHAR
如果你的代码是国际版本(多语言版)
你也可以用TCHAR.. 它是一个依赖识别字的宏 可以是char 也可以是wchar_t...
Ⅷ linux系统下WPS缺失字体导致文件乱码该怎么办
真的很正常,linux下经常出现乱码问题,这个跟编辑器的编码有关,至于wps,,你进wps的官方论坛,他们说这个问题很多次:
一下是官方的说明:
看涛哥讲故事讲的起兴,正好周末,我也上来讲讲故事哈。
随便挑了个主题,就讲“无尽混乱的编码吧”。
我想只要是玩linux的人,多多少少都遇到过乱码的问题吧,否则还真不能叫linux党。
wps运行时用的是什么编码?
wps运行时采用的是utf16编码,我相信在windows这是很多程序的选择。
但是坑爹的gcc竟然,它竟然只支持utf32编码?????gcc的wchar_t竟然是4字节的,4字节的!!!!
幸亏那个坑爹的c++0x新标准被我们赶上了,支持了所谓u"str"和U"str"新格式。u就是utf16,U就是utf32。
so,我们只能选用了gcc4.5作为我们的编译器,并且编写了一个宏__X(str),在windows展开为L #str,linux下展开为u #str。 (这也是很多朋友抱怨libstdc++版本过高的罪恶根源)
然后我们把工程里所有的L"xxx"改为了__X("xxx"),把工程里的所有wchar_t改为WCHAR// 囧,改的我们手脚发麻啊。
但是好景不长,没过两天就让我们知道,c++标准委员会绝对不是吃素的。这帮天煞的家伙不把c++搞的反人类就不爽。
strcmp是单字节的,wcscmp是4字节的,那两字节的是啥?????没有!上帝啊: c++0x是的,c++0x不是c0x。。。。。so,char16_t是没有c库支持的。这叫神马utf16支持啊。
一不做二不休,我们再把所有的字符串c标函数又实现了一遍,于是乎有了xstrcmp,xstricmp,xstrncmp....。然后继续改到手发麻。。。。
但是c艹还是觉得我们太悠闲了,so,下一句台词是: c++0x不是c0x,也不是c++。。。。是的,我们目前发现char16_t除了std::basic_string<char16_t>能链接通过以外没有发现系统库例子。
连正则表达式都不能用,// 朋友你想用?不好意思,我们还没实现,你再等等吧。。。。。
。。。。我感觉我们只剩下半管血了。c++标准委员会还是觉得意犹未尽啊。
在不和c兼容 & 半成品实现上, c++0x下一个坑我们的是char16_t,这个类型本身。对,他是一个类型,不是typedef unsigned short chart16_t。
so,工程里充斥满了QString::fromUtf16((WCHAR *)__X("what a bad day!!!"));
到最后我们终于受不了了,把__X的定义改成了 ((unsigned short *)(u #str))。
then....__X('x') 和 __X("adsf") __X("asdf") 和 WCHAR str[] = __X("asdf") 都顺利歇菜了。阿门
然后我们血条红了。。。
wps的源代码用的是什么编码?
这个不用想都知道,wps是从vc6年代过来的工程,vc6又不支持utf8,当然是ansi编码(GBK)的了。
移植到linux的时候,没多久我们就碰到了编码问题。
主要是2种情况。
1 gcc按照utf-8编码解释gbk文件,导致\n回车被吞。这个时候一旦使用\\形式的备注,编译就悲剧了。(/**/形式只要在*/前加入足量的空格就没问题)
2 字符串中本身存在非ascii字符。这种情况虽然不多,却是更加棘手。
于是在linux分支上,我们就将一部分文件转为了utf8。
但这是做了几天后我们就发现不对劲了。去vc上做了个实验,果然vc罢工了。
最后我们根据实验结果得出以下结论: vc支持ansi、utf8+bom、utf16+bom,gcc支持utf8、utf8+bom
于是我们经过商议后,得出结论: 把所有工作代码转为utf8+bom,以适应将来跨平台
步骤如下:
1 编写svn钩子,以进行强制编码检查
2 将主干转为utf8+bom
3 改写svn客户端,使得支持跨编码代码合并
4 所有的分支和主干合并后,重新拉取分支后变为utf8分支。
于是乎我很happy的将主干转为了utf8+bom,结果,结果编不过去了。~_~
然后才发现,天煞的windows资源编译器只支持ansi、utf16+bom
我勒个去啊,一交集,发现没答案了。
幸亏那部分文件,没包含非中文不行的字符,俺直接给那部分文件中文备注全给删除了,改成了英文备注,OK,过了
看了这个计划,大家就知道最头大的在3和4两个步骤。
其他分支还好,文件编码基本都是ansi的,合并的时候基本没压力。
linux分支的文件有很多都是utf8没bom的。
然后俺又做了搓事啊,悲剧svn客户端没改好,编码猜测部分代码除了BUG。然后。。。。。
然后俺就拉着一帮小弟,人肉fixup啊。。。。。。。。。。