同样单字符和宽字符转换的的C++代码,VC下正常,QT下异常

sty_app 2021-02-26 10:17:52
上QT源码:

#include <QCoreApplication>
#include <QDebug>
#include <iostream>
using namespace std;

std::string ws2s(const std::wstring &ws)
{
size_t i;
std::string curLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "");
const wchar_t* _source = ws.c_str();
size_t _dsize = 2 * ws.size() + 1;
char* _dest = new char[_dsize];
memset(_dest, 0x0, _dsize);
wcstombs_s(&i, _dest, _dsize, _source, _dsize);
std::string result = _dest;
delete[] _dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}

std::wstring s2ws(const std::string &s)
{
size_t i;
std::string curLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "chs");
const char* _source = s.c_str();
size_t _dsize = s.size() + 1;
wchar_t* _dest = new wchar_t[_dsize];
wmemset(_dest, 0x0, _dsize);
mbstowcs_s(&i, _dest, _dsize, _source, _dsize);
std::wstring result = _dest;
delete[] _dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}


int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::string strTest = "1234中文abcd";
std::wstring destWStr = s2ws(strTest);
return a.exec();
}

执行效果:



上VS源码:

#include <afx.h>
#include <string>
#include <iostream>
using namespace std;

#pragma warning (disable: 4996)

std::string ws2s(const std::wstring &ws)
{
size_t i;
std::string curLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "");
const wchar_t* _source = ws.c_str();
size_t _dsize = 2 * ws.size() + 1;
char* _dest = new char[_dsize];
memset(_dest, 0x0, _dsize);
wcstombs_s(&i, _dest, _dsize, _source, _dsize);
std::string result = _dest;
delete[] _dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}

std::wstring s2ws(const std::string &s)
{
size_t i;
std::string curLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "");
const char* _source = s.c_str();
size_t _dsize = s.size() + 1;
wchar_t* _dest = new wchar_t[_dsize];
wmemset(_dest, 0x0, _dsize);
mbstowcs_s(&i, _dest, _dsize, _source, _dsize);
std::wstring result = _dest;
delete[] _dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}

int main()
{
std::string strTest = "1234中文abcd";
std::wstring destWStr = s2ws(strTest);
return 0;
}


VS执行结果:

...全文
272 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
sty_app 2021-03-04
  • 打赏
  • 举报
回复
引用 13 楼 真相重于对错 的回复:
[quote=引用 11 楼 sty_app 的回复:][quote=引用 10 楼 真相重于对错 的回复:]qt下直接用qstring处理比较简单


要写一份跨平台跨编译器的代码。 QString不行[/quote]
qstring 是qt亲生的,怎么不行?[/quote], 领导要求,能用标c++的尽量用 标c++实现。字符串转换应该属于很基础的内容了,没必要用QT的QString
真相重于对错 2021-03-03
  • 打赏
  • 举报
回复
引用 11 楼 sty_app 的回复:
[quote=引用 10 楼 真相重于对错 的回复:]qt下直接用qstring处理比较简单
要写一份跨平台跨编译器的代码。 QString不行[/quote] qstring 是qt亲生的,怎么不行?
  • 打赏
  • 举报
回复
引用 9 楼 sty_app 的回复:
[quote=引用 6 楼 早打大打打核战争 的回复:]代码写复杂了,可以简化一些:

#include <codecvt>

std::string ws2s(const std::wstring &ws)
{
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10fffful,
std::codecvt_mode::little_endian>, wchar_t> cv;

//std::locale::global(std::locale(""));
//setlocale(LC_CTYPE, "");
return cv.to_bytes(ws);
}

std::wstring s2ws(const std::string &s)
{
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10fffful,
std::codecvt_mode::little_endian>, wchar_t> cv;

//std::locale::global(std::locale(""));
//setlocale(LC_CTYPE, "");
return cv.from_bytes(s);
}

貌似不行哦

[/quote]

程序输出一下看看
sty_app 2021-03-03
  • 打赏
  • 举报
回复
引用 10 楼 真相重于对错 的回复:
qt下直接用qstring处理比较简单


要写一份跨平台跨编译器的代码。 QString不行
真相重于对错 2021-03-01
  • 打赏
  • 举报
回复
qt下直接用qstring处理比较简单
sty_app 2021-03-01
  • 打赏
  • 举报
回复
引用 6 楼 早打大打打核战争 的回复:
代码写复杂了,可以简化一些:

#include <codecvt>

std::string ws2s(const std::wstring &ws)
{
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10fffful,
std::codecvt_mode::little_endian>, wchar_t> cv;

//std::locale::global(std::locale(""));
//setlocale(LC_CTYPE, "");
return cv.to_bytes(ws);
}

std::wstring s2ws(const std::string &s)
{
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10fffful,
std::codecvt_mode::little_endian>, wchar_t> cv;

//std::locale::global(std::locale(""));
//setlocale(LC_CTYPE, "");
return cv.from_bytes(s);
}

貌似不行哦

sty_app 2021-03-01
  • 打赏
  • 举报
回复
引用 4 楼 赵4老师 的回复:
[quote=引用 3 楼 sty_app 的回复:][quote=引用 2 楼 芒果黑 的回复:]Qt msvc编译器用你的代码试了没问题 不要在代码直接给中文 从文件读试试看 可能是你Qt Creator配置的问题


我感觉是编码格式的问题, 但在哪里改 不太清除。[/quote]
源代码另存为,选你希望的字符编码,……[/quote]

VScpp文件默认使用的是 GBK, QTcpp文件默认使用的是 UTF-8。
相同源码,运行过程中实际占用的内存并不一致。
sty_app 2021-03-01
  • 打赏
  • 举报
回复
引用 5 楼 丁劲犇 的回复:
如果你的qt用的是VC编译器。用记事本打开你的cpp,另存为gb2312
如果你的qt用的是。mibgw编译器,另存为utf-8


所以说是本地文件的编码格式导致 运行过程中内存提示异常吧。
  • 打赏
  • 举报
回复
代码写复杂了,可以简化一些:

#include <codecvt>

std::string ws2s(const std::wstring &ws)
{
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10fffful,
std::codecvt_mode::little_endian>, wchar_t> cv;

//std::locale::global(std::locale(""));
//setlocale(LC_CTYPE, "");
return cv.to_bytes(ws);
}

std::wstring s2ws(const std::string &s)
{
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10fffful,
std::codecvt_mode::little_endian>, wchar_t> cv;

//std::locale::global(std::locale(""));
//setlocale(LC_CTYPE, "");
return cv.from_bytes(s);
}

丁劲犇 2021-02-27
  • 打赏
  • 举报
回复
如果你的qt用的是VC编译器。用记事本打开你的cpp,另存为gb2312 如果你的qt用的是。mibgw编译器,另存为utf-8
芒果黑 2021-02-26
  • 打赏
  • 举报
回复
Qt msvc编译器用你的代码试了没问题 不要在代码直接给中文 从文件读试试看 可能是你Qt Creator配置的问题
赵4老师 2021-02-26
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A
赵4老师 2021-02-26
  • 打赏
  • 举报
回复
引用 3 楼 sty_app 的回复:
[quote=引用 2 楼 芒果黑 的回复:]Qt msvc编译器用你的代码试了没问题 不要在代码直接给中文 从文件读试试看 可能是你Qt Creator配置的问题
我感觉是编码格式的问题, 但在哪里改 不太清除。[/quote] 源代码另存为,选你希望的字符编码,……
sty_app 2021-02-26
  • 打赏
  • 举报
回复
引用 2 楼 芒果黑 的回复:
Qt msvc编译器用你的代码试了没问题 不要在代码直接给中文 从文件读试试看 可能是你Qt Creator配置的问题


我感觉是编码格式的问题, 但在哪里改 不太清除。
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质?你是否想成为一名资深开发人员,想开发别人做不了的高性能程序?你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? 那么C++就是你个人能力提升,职业之路进阶的不二之选。【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署;2.吊打一切关于C++的笔试面试题;3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块基础篇本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。进阶篇本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。提升篇:本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
鸣谢 首先要感谢linus,给了我们一个可以自由翱翔的平台; 其次,要感谢网络上千万的linux/windows先行者,给予的有意或无意的指点和帮助; 再次,感谢陈皓兄的《跟我一起写makefile》,引导我走过了makefile的迷雾。后来发现于凤昌兄译的《GNU Make使用手册》,也有颇多受益。 背景 从2004年,我在一个公司作服务端软件的开发,要支持linux/windows平台,主要是为了容易维护,就设计、开发了这一套比较常用的类。 2005一直在windows下作IPTV的开发,在2006年底,又回到linux下作IPV6下IPTV的开发。在空闲时间,看看两年前的那些零散类文件,开始整理这些类成库,并写了简的使用和测试范例,放在网上和朋友们共享。 由于早期的平台从windows98和VC6.0,redhat8.0,经历了些变迁,没有太多的时间再一一仔细测试,就用现在的windowsXP和VS.2003,Fedaro Core4.0作的测试。 主要是为了相互学习,希望能和朋友们共同进步!如有引用,请标明出处,会不胜感激!禁止商业性的书籍的引用!很多不良的作者,完全是在骗钱。 功能简介 通用于linux/windows平台C++的应用。 主要是对一些系统功能,进行了简洁封装。 主要有读写锁类, 线程类, 线程池类, 定时器类, socket1.1的封装类, ini文件类, txt文件类, 可删除内容的文件类, 查找文件类, 调试输出类, 字符串类, 同步的普通队列和优先级队列类, 智能指针和内存自动管理类,数据库类. 特别声明:因为环境限制,这次测试代码中,没有测试数据库类。我以前也只是在PostgreSQL,SQL Server2000和Acess2000中实际用过。如有朋友用到,请自行修改、测试。 这些类的风格,与个人习惯密切相关。推荐QT,跨平台的类库,还是不错的;ACE就太难使用了! 编译和运行: 1. windwos下,用vs2003打开pub下的test.sln文件,所有的测试程序和类库文件就载入,编译即可。其它程序引用库时,请选中/MDd选项。 2. linux下,执行pub下的Makefile文件,编译即可。如果没有安装PostgreSql,数据库部分会编译不过。 关于inline函数 我写的这些类的函数,大部分是可以写成inline函数的,对性能提高也有很大的帮助。但是,GCC和VC的不同版本编译器的支持程度不同,可能会编译不过,所以就都没有为提高效率而写inline函数。依赖于编译器,对跨平台的程序来说,也比较麻烦! 不过,现在的硬件系统,对这些小小的性能提升,也感觉不出来的。 如有需要,请自行改写! 关于异常和错误处理 也是仁者见仁,智者见智! 习惯于C开发的朋友,大概喜欢函数错误时返回错误码。函数有返回值,就要处理,就使程序逻辑较为复杂,看去也比较的混乱。 我则喜欢用异常代替,主要是代码简洁和逻辑清晰。异常抛掷,会使流程很简洁,只显示执行正确时的流程,错误集中处理 对于那些失败即意味着中止的一个操作,我让其抛掷异常。如果是正常的分支流程,则用返回失败值。就我遇到的情况,大部分则为操作失败,调用的流程一般都要中止的。 这个判断也是比较难下的。放在一个局部,异常可能导致操作中止;但放在更上一层,则异常又可能是正确程序流程处理。 bug的反馈和修改支持 如果有重大的错误需要偶修正,请发到linhweikuo@hotmail.com的邮箱,尽量说明问题的现象,我会在一周内解决的(如果工作比较紧急的时候,不能即时就处理的)。

24,852

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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