C++ 将 _TCHAR* 转换为 char*

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19301538/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:41:39  来源:igfitidea点击:

Converting _TCHAR* to char*

c++stringvisual-c++atltchar

提问by dumbledad

I'm trying to get a simple OpenCV sampleworking in C++ on Windows and my C++ is more than rusty.

我正在尝试在 Windows 上使用 C++获取一个简单的 OpenCV 示例,而我的 C++ 不仅仅是生疏。

The sampleis fairly simple:

示例相当简单:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
    if( argc != 2)
    {
        cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
        return -1;
    }
    Mat image;
    image = imread(argv[1], IMREAD_COLOR); // Read the file
    if(! image.data )                      // Check for invalid input
    {
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    }
    namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
    imshow( "Display window", image );                // Show our image inside it.
    waitKey(0); // Wait for a keystroke in the window
    return 0;
}

When I make a new simple C++ console application (with ATL) in Visual Studio 2012 I get a different template for main:

当我在 Visual Studio 2012 中创建一个新的简单 C++ 控制台应用程序(使用 ATL)时,我得到了一个不同的模板main

int _tmain( int argc, _TCHAR* argv[] )

So before I send the filename to OpenCV's imreadfunction I need to convert the _TCHAR*arg[1]to a char*. Using a simple filename, 'opencv-logo.jpg', from the memory in the memory window I can see that the _TCHAR are taking two bytes each

所以,在我的文件名发送到OpenCV的的imread功能,我需要将转换_TCHAR*arg[1]char*。使用简单的文件名“opencv-logo.jpg”,从内存窗口的内存中我可以看到 _TCHAR 每个占用两个字节

o.p.e.n.c.v.-.l.o.g.o...j.p.g...
6f 00 70 00 65 00 6e 00 63 00 76 00 2d 00 6c 00 6f 00 67 00 6f 00 2e 00 6a 00 70 00 67 00 00 00

Following the conversion recommendation in another answerI am trying to use ATL 7.0 String Conversion Classes and Macrosby inserting the following code:

按照另一个答案中的转换建议,我尝试通过插入以下代码来使用ATL 7.0 字符串转换类和宏

char* filename = CT2A(argv[1]);

But the resulting memory is a mess, certainly not 'opencv-logo.jpg' as an ascii string:

但由此产生的内存是一团糟,当然不是 'opencv-logo.jpg' 作为 ascii 字符串:

fe fe fe fe fe fe fe fe fe fe ...
tttttttttt ...

Which conversion technique, function, or macro should I be using?

我应该使用哪种转换技术、函数或宏?

(N.B. Thismay be a related question but I cannot see how to apply the answerhere.)

(注意可能是一个相关的问题,但我看不到如何此处应用答案。)

回答by bames53

The quickest solution is to just change the signature to the standard one. Replace:

最快的解决方案是将签名更改为标准签名。代替:

int _tmain( int argc, _TCHAR* argv[] )

With

int main( int argc, char *argv[] )

This does mean on Windows that the command line arguments get converted to the system's locale encoding and since Windows doesn't support UTF-8 here not everything converts correctly. However unless you actually need internationalization then it may not be worth your time to do anything more.

这确实意味着在 Windows 上,命令行参数被转换为系统的区域设置编码,并且由于 Windows 不支持 UTF-8,因此并非所有内容都能正确转换。但是,除非您确实需要国际化,否则可能不值得花时间做更多事情。

回答by LihO

_TCHAR, i.e. TCHARis a type that depends on your project's settings. It can be either wchar_t(when you use Unicode) or char(when you use Multi-byte). You will find this in Project Properties- General, there's a setting Character Set.

_TCHAR, ieTCHAR是一种取决于您的项目设置的类型。它可以是wchar_t(当您使用 Unicode 时)或char(当您使用多字节时)。您会在Project Properties- General 中找到它,有一个设置Character Set

Probably the simplest thing that you could do is just to use multi-byte option and treat _TCHAR*type as a simple char*and use it to construct std::stringobject ASAP:

可能你能做的最简单的事情就是使用多字节选项并将_TCHAR*类型视为简单char*并使用它来std::string尽快构造对象:

std::string filename(argv[1]);


But in case you are going to work with special characters A LOT, then I find it more reasonable to use Unicode and hold strings in form of std::wstringobjects wherever it's possible. If that's the case, then just use std::wstring's constructor instead:

但是,如果您要使用很多特殊字符,那么我发现使用 Unicode 并std::wstring尽可能以对象形式保存字符串更为合理。如果是这种情况,那么只需使用std::wstring的构造函数:

std::wstring filename(argv[1]);

And in case you'll end up working with wide strings, sometimes you'll need a conversion between wide strings and multi-byte strings and these helpers might help you:

如果您最终要使用宽字符串,有时您需要在宽字符串和多字节字符串之间进行转换,这些助手可能会帮助您:

// multi byte to wide char:
std::wstring s2ws(const std::string& str)
{
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
    std::wstring wstrTo(size_needed, 0);
    MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
    return wstrTo;
}

// wide char to multi byte:
std::string ws2s(const std::wstring& wstr)
{
    int size_needed = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), 0, 0, 0, 0); 
    std::string strTo(size_needed, 0);
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), &strTo[0], size_needed, 0, 0); 
    return strTo;
}

回答by yevgeniy litvinov

other than reading the 26,000 page cpp 2003 VS manual which hasn't changed much.... std::string test(print); test = "";

除了阅读没有太大变化的 26,000 页 cpp 2003 VS 手册之外…… std::string test(print); 测试 = "";

int _tmain( int argc, _TCHAR* argv[] )  

int main( int argc, char *argv[] ) 

work the same unless you were using some securitys function.... and couldn't be unicode in the character set property ... if you were to use the CreateFile function in file Management Functions unless you multi-threaded it somehow

除非你使用一些安全功能......并且不能在字符集属性中使用unicode,否则工作相同......如果你要在文件管理功能中使用CreateFile函数,除非你以某种方式对其进行多线程处理