我正在阅读关于Windows上的字符集和编码.我注意到Visual Studio编译器(用于C++)中有两个编译器标志,称为MBCS和UNICODE.他们之间有什么区别?我没有得到的是UTF-8在概念上与MBCS编码有何不同?另外,我在MSDN中找到以下引用:
Unicode是一种16位字符编码
这否定了我读到的关于Unicode的任何内容.我认为unicode可以使用不同的编码进行编码,例如UTF-8和UTF-16.有人能否对这种混乱有所了解?
Windows _setmbcp函数允许任何有效的代码页...
(UTF-7和UTF-8除外,不支持)
好的,不支持UTF-7是有道理的:字符具有非唯一的表示形式,并且会带来复杂性和安全风险.
但为什么不是UTF-8?
据我所知,Windows API函数的"ANSI"版本将其参数转换为UTF-16,调用等效的"W"函数,并将输出中的任何字符串转换为"ANSI".这就是我一直在手动做的事情.那么为什么Windows不能为我做呢?
因此,进入新千年我改写了我的c ++代码:
int main(int argc, wchar_t **argv)
Run Code Online (Sandbox Code Playgroud)
如果使用Unicode或MBCS选项构建,那么当使用命令行arg运行应用程序时,直接或通过dbl-click传递给argv []的文件名是不可读的=在某些混合的中文字体中.
感谢您的评论 - 我将尝试在这里总结(z)e为搜索引擎.
wmain(int argc,char **argv) 只能用于命令行(子系统:控制台)应用程序
int winMain(int argc, wchar_t **argv)适用于gui(子系统:windows),但gui用它自己的入口点替换它.在Qt的情况下,这不起作用
qtmaind.lib(qtmain_win.obj):错误LNK2019:函数_WinMain @ 16中引用了未解析的外部符号_main
解决方案似乎是使用main(int arc,char **argv)
或main(int argc,wchar_t**argv)忽略argv.然后用argv或NULL调用QApplication - 由于Qt内部调用GetCommandLine(),因此忽略argv.
然后使用app.arguments返回已解析的参数.
然后,如果需要,可以使用Qt的字符串函数将它们转换回wchar.
QApplication app(argc, (char**)argv); or QApplication app(argc,NULL);
QStringList args = app.arguments();
Run Code Online (Sandbox Code Playgroud)
对不起,我最初没有标记这个Qt,因为我认为这不相关.
如果有人想编辑它还包括如何在MFC中执行此操作 - 请执行此操作.
我正在修改一些非常古老的(10年)C代码.该代码在Unix/Mac上使用GCC进行编译,并使用MinGW对Windows进行交叉编译.目前整个都有TCHAR字符串.我想摆脱TCHAR并使用C++字符串代替.是否仍然需要使用Windows范围的功能,或者我现在可以使用Unicode和UTF-8完成所有操作吗?
我想用C++编写一个应该在Unix和Windows上运行的程序.该程序应该能够同时使用:Unicode和非Unicode环境.其行为应仅取决于环境设置.
我想要的一个很好的功能是操作从目录中读取的文件名.这些可以是unicode ......或者不是.
实现这一目标的最简单方法是什么?
我是C++编码的新手,来自Java和C#背景.我对最基本的#define术语的扩散感到困惑:
#define _tmain wmain
Run Code Online (Sandbox Code Playgroud)
当我第一次学习C语言时,我的主要功能是:
int main(int argc, char *argv[])
Run Code Online (Sandbox Code Playgroud)
在我创建的Visual C++项目中,它创建了主要功能:
int _tmain(int argc, _TCHAR* argv[])
Run Code Online (Sandbox Code Playgroud)
我只是想知道为什么要起个名翻译需要wmain来_tmain?为什么不使用原始的C main函数原型?
一般来说,似乎有很多#define重命名的东西,看起来很清楚,看起来更神秘,更不清楚(我的意思wmain是_tmain?).
感谢您容忍可能是一个非常明显的问题.
我正在用c ++为Windows编写一个新的(个人爱好)应用程序.
在以前的低级Windows中,我使用_TCHAR(或只是TCHAR)数组/ basic_strings进行字符串操作.
如果我不关心Win2k之前的Windows平台,那么使用_TCHAR直接使用Unicode 是否有任何优势?wchar_t
编辑:提交后我在2008年10月发现了一个类似的问题:
现在似乎对放弃TCHAR更加一致
我正在开发一个主要由英语和西班牙语读者使用的应用程序.但是,将来我希望能够支持更多扩展语言,例如日语.在考虑该程序的设计时,我已经在UTF-8与UTF-16与多字节中碰壁.我想编译我的程序以支持UTF-8或UTF-16(对于使用中文等语言的情况).为了实现这一点,我想我应该有类似的东西
#if _UTF8
typedef char char_type;
#elif _UTF16
typedef unsigned short char_type;
#else
#error
#endif
Run Code Online (Sandbox Code Playgroud)
这样,将来当我使用UTF-16时,我可以切换#define(当然,对于诸如此类的东西,它们具有相同类型的#if /#endif sprintf).我有自己的自定义字符串类型,所以也可以使用这种情况.
使用上面提到的场景替换每次只使用"char"与我的"char_type"的用法,会被视为"坏主意"吗?如果是这样,为什么它被认为是一个坏主意,我怎么能实现我上面提到的?
我想使用其中一个的原因是由于内存效率.如果我不使用它,我宁愿不要一直使用UTF-16.
考虑:
#include <iostream>
#include <vector>
class A
{
public:
typedef bool TAll;
static TAll All;
typedef std::vector<int> TVec;
static TVec m_sVec;
static TVec::iterator begin() { return m_sVec.begin(); }
static TVec::iterator end() { return m_sVec.end(); }
};
A::TVec A::m_sVec;
A::TAll A::All;
A::TVec::iterator begin(A::TAll& all) { return A::begin(); }
A::TVec::iterator end(A::TAll& all) { return A::end(); }
int _tmain(int argc, _TCHAR* argv[])
{
A::m_sVec.push_back(1);
A::m_sVec.push_back(2);
A::m_sVec.push_back(3);
for (auto a : A::All) {
//for (auto a = begin(A::All); a != end(A::All); a++) {
std::cout …Run Code Online (Sandbox Code Playgroud) 什么是TCHAR字符串,例如LPTSTR和LPCTSTR我如何使用它们?当我在Visual Studio中创建一个新项目时,它为我创建了这个代码:
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
例如,我如何连接所有命令行参数?
如果我想打开第一个命令行参数给出的名称的文件,我该怎么做?Windows API定义了许多函数的"A"和"W"版本,例如CreateFile,CreateFileA和CreateFileW; 那么这些如何彼此不同以及我应该使用哪一个?
GDI +使用WCHAR而不是WinAPI允许的CHAR.通常我可以这样做:
char *str = "C:/x.bmp";
Run Code Online (Sandbox Code Playgroud)
但我如何为wchar做这个?我不能这么做
wchar_t *file = "C:/x.bmp";
Run Code Online (Sandbox Code Playgroud)
谢谢
我需要从文件名中获取扩展名并将其与我的扩展数组进行比较.但看起来像TCHAR没有类似strpos()函数,所以我走了一个数组TCHAR(不是最好的解决方案?)来搜索'.'符号并提取文件扩展名.但它不起作用.
for (int i = 0; i < extCount; i++)
{
//wsprintf(fileName, L"%d", extCount);
//_tcscpy_s(fileName, extensions[i]);
_tcscpy_s(fileName, fileData.cFileName);
for (int k = wcslen(fileName); k >= 0; k--)
{
if (fileName[k] == (LPCWSTR)TCHAR('.'))
{
wsprintf(temp, L"%c", fileName[k]);
MessageBox(NULL, fileName[k], L"????", MB_OK);
}
}
Run Code Online (Sandbox Code Playgroud)
所以问题是,如何以最简单和最有效的方式获取和比较文件扩展名?还有一个问题 - 我真的应该使用TCHAR吗?因为这种类型有很多麻烦.他们什么时候练习?
我正在尝试将字符串转换为'LPCTSTR',但是,我得到了以下错误.
错误:
cannot convert from 'const char *' to 'LPCTSTR'
Run Code Online (Sandbox Code Playgroud)
码:
std::string str = "helloworld";
LPCTSTR lp = str.c_str();
Run Code Online (Sandbox Code Playgroud)
还试过:
LPCTSTR lp = (LPCTSTR)str.c_str();
Run Code Online (Sandbox Code Playgroud)
但是,打印垃圾值.