编程中的中文字符处理

编程入门 行业动态 更新时间:2024-10-06 10:26:08

编程中的<a href=https://www.elefans.com/category/jswz/34/1769975.html style=中文字符处理"/>

编程中的中文字符处理

文章目录

    • 前言
    • 中文在不同编码环境下的处理
      • 程序在单一系统上运行
      • 程序在多个系统上运行
    • 中文在相同编码不同存储类型下的处理

前言

编程遇到中文的时候,需要注意下。其一,软件中使用的编码,与软件运行环境的编码是否一致。比如,在客户端编程中,编程界面使用utf-8编码,而运行程序的win环境是gb2312编码,则显示会乱码。其二,以何种数据结构存储包含中文的变量。比如,如果使用string结构存储可能包含中文的配置文件路径,处理不当,函数加载配置文件可能失败。

下面两个小结,将会讨论上面两点。在讨论之前,我们需要对编码有基本的认知。我之前整理过文件乱码处理,我个人的背景知识点中包含编码的基本常识,所以本文不包含编码的基本介绍。另外,我这里简单补充下常见的编程环境,使用的编码方式。

  • linux系统 -> vscode 编辑器 -> utf-8编码
  • win11系统 -> vscode 编辑器 -> utf-8编码
  • win11系统 -> vs 编辑器 -> gb2312编码

中文在不同编码环境下的处理

程序在单一系统上运行

如果程序仅仅运行在linux环境下,整个程序项目文件,可以保存为utf-8格式。

如果程序仅仅运行在windows环境下,整个程序项目文件,可以保存为gb2312格式。

虽然程序仅仅运行在单一环境下,但程序员的开发环境可能是千奇百怪。EditorConfig似乎可以解决这个问题。但是我没折腾出来,EditorConfig并没有修改文件的编码。

程序在多个系统上运行

对于需要显示中文的跨平台客户端程序,如使用qt、electron、cef等框架开发的软件,应该结合框架,解决不同系统的编码问题。如:彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)_libaineu2004的博客-CSDN博客_qt中文乱码

非必要显示中文的地方,尽量使用英文。

没有使用框架,而又不得不处理不同系统间的编码问题,可以考虑借助std::basic_string - cppreference来实现utf-8和gbk之间的转换。(PS: [日常]GB2312 GBK GB18030的区别和演进过程_陶士涵的菜地的技术博客_51CTO博客)

这里从网上找了几个函数:C++11 字符串编码转换_帝江VII的博客-CSDN博客_c++11编码转换

// utf-8转gbk
std::string utf8_to_gbk(const std::string& str)
{std::wstring_convert<std::codecvt_utf8<wchar_t> > conv;std::wstring tmp_wstr = conv.from_bytes(str);//GBK locale name in windowsconst char* GBK_LOCALE_NAME = ".936";std::wstring_convert<std::codecvt_byname<wchar_t, char, mbstate_t>> convert(new std::codecvt_byname<wchar_t, char, mbstate_t>(GBK_LOCALE_NAME));return convert.to_bytes(tmp_wstr);
}
//gbk转utf-8
std::string gbk_to_utf8(const std::string& str)
{//GBK locale name in windowsconst char* GBK_LOCALE_NAME = ".936";std::wstring_convert<std::codecvt_byname<wchar_t, char, mbstate_t>> convert(new std::codecvt_byname<wchar_t, char, mbstate_t>(GBK_LOCALE_NAME));std::wstring tmp_wstr = convert.from_bytes(str);std::wstring_convert<std::codecvt_utf8<wchar_t>> cv2;return cv2.to_bytes(tmp_wstr);
}

如果使用boost,可以考虑使用下面函数。

inline std::string utf8_to_gbk(const std::string &str) {return boost::locale::conv::between(str, "GBK", "UTF-8");
}inline std::string gbk_to_utf8(const std::string &str) {return boost::locale::conv::between(str, "UTF-8", "GBK");
}

中文在相同编码不同存储类型下的处理

当编码一致之后,还得考虑相同的字符串内容,在不同存储类型之间的转换,特别是有windows环境编程时。比如,我们通常使用std::string来保存字符串,里面是否有中文,并不在意,因为只需要一个结构来存储。但是,当使用windows api来处理这些字符串的时候,就稍微有些头疼。比如ExtractIconExA function (shellapi.h) - Win32 apps | Microsoft Docs函数,需要传入一个LPCTSTR类型的路径,而我们使用stiring来保存路径。此时,需要进行一些类型转换。

在此之前,我们先瞅瞅有哪些类型可以表示一个字符串

windows环境编程中,字符串的表示,参考:Windows Data Types (BaseTsd.h) - Win32 apps | Microsoft Docs、LPSTR、LPCSTR、LPTSTR、LPCTSTR、LPWSTR及LPCWSTR的意义及区别_hellokandy的博客-CSDN博客

  • [MS-DTYP]: LPSTR | Microsoft Docs :指定了一个指向 8 位字符数组的指针,该数组可以由一个空字符终止。(当作char*使用)

  • [MS-DTYP]: LPCSTR | Microsoft Docs:指向一个由 8 位 Windows (ANSI) 字符组成的以空字符结尾的常量字符串。(当作const char*使用)

  • [MS-DTYP]: LPWSTR | Microsoft Docs:指向一个由 16 位Unicode 字符组成的字符串,它可以以空字符结尾。(当作wchar_t*使用)

  • [MS-DTYP]: LPCWSTR | Microsoft Docs :(当作const LPWSTR )

  • LPTSTR:如果是UNICODE编码,则表示为LPWSTR;否则,表示为LPSTR。

  • LPCTSTR:(当作const LPTSTR)

在上面的类型中,L表示long, P表示指针,C表示constant, T表示指针指向的字符占的字节数取决于Unicode是否定义,W表示wide,STR就是string的意思。

如果需要一些强制类型转换,可以参考:c++ - How to convert std::string to LPCSTR? - Stack Overflow

// sting到LPSTR的转换(下面的代码注意生命周期)(本质没有改变)
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());
// 将字符串映射成utf-16
// 代码来自:
wstring ANSIToUnicode(string str)
{int lengthW = MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,NULL,NULL);wchar_t* pUnicode = new wchar_t [lengthW*sizeof(wchar_t)];memset(pUnicode,0,lengthW*sizeof(pUnicode));MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,pUnicode,lengthW);wstring strw = pUnicode;delete[] pUnicode;return strw;
}

另外有几个宏,可以用以方便的转换:A2W、W2A、A2T、T2A的使用方法

更多推荐

编程中的中文字符处理

本文发布于:2024-02-14 12:02:36,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1763051.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:中文   字符

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!