Windows下Qt调用C++命令行程序——参数传递、字符编码转换

xiaoxiao2021-02-28  51

        最近做的一个小项目,涉及到Qt调用VS生成的C++命令行程序,要求满足对任意字符的编码,都能在命令行程序里面,完成读写文本文件和正确显示的要求,例如字符串“中文English☯☰☷♥♠”。由于对C++操作和编码概念的不熟悉,走了一点弯路,现在把一部分内容分享出来,希望对其他同学有所帮助。

一、Qt命令行调用和传参分析

       Qt调用命令行程序,有如下链接可以参考:http://blog.csdn.net/jaster_wisdom/article/details/70154253,其中需要注意的是QProcess有一个finished()的信号,可利用其进行异步编程。对于QProcess::start(QString&,QStringList &),其中第一个参数是命令行程序的路径,第二个参数是需要传给该命令行程序的参数。可见,Qt是以QStringList组织参数传出去的,实际上可以认为是以QString的形式传出去的。经过在命令行程序段的检测,最终命令行程序接收到的参数是以宽字节wchar_t*的形式传入的。

       综上分析,对于VS的C++命令行程序,将接收到宽字节wchar_t*形式的传入参数,以utf-8编码。因此不能使用int main(int argc,charargv[])或int main(int argc,wchar_targv[]),而应该使用int wmain(int argc,wchar_targv[])。下面的测试代码是命令行程序里面的一系列输入、转换、打印等操作,可以应对不同场合、不同接口的需求。

 

二、命令行程序测试代码:

#include<fcntl.h> #include<io.h> #include<stdio.h> #include<iostream> #include<atlstr.h> usingnamespace std; int wmain( intargc, wchar_t* argv[] ) { //设置console输入输出流为宽字节 _setmode(_fileno(stdin), _O_U16TEXT); _setmode(_fileno(stdout), _O_U16TEXT); //console获取输入,console输出 wchar_t* input_text = newwchar_t[100]; wcout <<"input a string:"; wcin >> input_text; wprintf(L"\ninput_text:\n\t%ls\n\n", input_text); //直接赋值wchar,console输出 wchar_t* assign_text = L"中文English☯☰☷♥♠"; wprintf(L"assign_text:\n\t%ls\n\n", assign_text); //wmain获取wchar,console输出 wchar_t* argv_text = argv[1]; wcout <<L"argv_text:\n\t"<< argv_text <<"\n\n"; //utf-8转ascii存储,console输出 std::string stdchar_text= CW2A(argv[1], CP_UTF8); wcout <<L"stdchar_text:\n\t"<< stdchar_text.c_str() <<"\n\n"; //ascii转unicode,console输出 wstring recover_text = CA2W(stdchar_text.c_str(), CP_UTF8); wcout <<L"recover_text:\n\t"<< recover_text.c_str() <<"\n\n"; ascii转ansi,console输出 wstring ansi_text = CA2W(stdchar_text.c_str()); wcout <<L"ansi_text:\n\t"<< ansi_text.c_str() <<"\n\n"; return 0; }

三、命令行程序运行结果:

                                       

        可以看到,程序中支持任意utf-8字符的console窗口输入和输出,并且能从命令行参数wchar_t *argv[]正确获取utf-8字符数据。此外,还在Windows平台下完成了ascii、utf-8、ansi之间的互相转码操作,因此这一个例子可以加深对编码、转码等的理解。

四、代码分析:

1、只有wmain可以接受宽字节字符串参数wchar_t*。

2、_setmode(_fileno(stdin),_O_U16TEXT)和_setmode(_fileno(stdout),_O_U16TEXT)用来支持console对任意utf-8字符的打印输出。

3、wcin或wscanf可以用来接收任意utf-8宽字符的键盘输入。

4、wout或wprintf用来打印输出utf-8宽字符。

5、后面还提供了3种编码方式的转换,注意CW2A和CA2W是Windows下的调用接口。

6、不同的编码转换可用来适应不同的场合。例如,有些库只接受std::string(ascii存储)的utf-8数据,而用户从console输入的却是wchar_t的utf-8数据,就可以利用代码中的utf-8转ascii存储来完成编码转换。

转载请注明原文地址: https://www.6miu.com/read-45948.html

最新回复(0)