Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ visualc&x2B+;:迁移传统的C和C++;Unicode世界的字符串代码_C++_C_Unicode_String - Fatal编程技术网

C++ visualc&x2B+;:迁移传统的C和C++;Unicode世界的字符串代码

C++ visualc&x2B+;:迁移传统的C和C++;Unicode世界的字符串代码,c++,c,unicode,string,C++,C,Unicode,String,我看到VisualStudio2008和更高版本现在开始使用字符集为Unicode的新解决方案。我的旧C++代码只处理英文ASCII文字,而且充满了: 文本字符串,如“Hello World” char类型 char*指向已分配C字符串的指针 STL字符串类型 使用STL string构造函数(它接受const char*)和STL string.C_str()将STL string转换为C string,反之亦然 为了迁移此代码,使其在VisualStudioUnicode和启用Unicod

我看到VisualStudio2008和更高版本现在开始使用字符集为Unicode的新解决方案。我的旧C++代码只处理英文ASCII文字,而且充满了:

  • 文本字符串,如
    “Hello World”
  • char
    类型
  • char*
    指向已分配C字符串的指针
  • STL字符串
    类型
  • 使用
    STL string
    构造函数(它接受
    const char*
    )和
    STL string.C_str()将
    STL string
    转换为C string,反之亦然

  • 为了迁移此代码,使其在VisualStudioUnicode和启用Unicode的库的生态系统中工作,我需要做哪些更改?(我不需要它同时使用ASCII和Unicode,它可以是纯Unicode。)

  • 是否也可以以独立于平台的方式执行此操作?(即,不使用Microsoft类型。)

我看到如此多的宽字符和Unicode类型和转换分散在各处,因此我感到困惑。(例如:wchar\u t、TCHAR、\u t、\u TEXT、TEXT等)

  • 在文字常量周围加上_T(),例如_T(“Hello world”)
  • char
    替换为宏
    char
  • 字符串替换为wstring
然后一切都会好起来。

“你好,世界”->L“你好,世界”

char->wchar\u t(除非您确实需要char)

char*->wchar\t*

字符串->字符串

这些都是独立于平台的。但是,请注意,宽字符在不同平台上可能不同(windows上为两个字节,其他平台上为四个字节)


在项目中定义UNICODE和_UNICODE(在Visual Studio中,可以通过在设置中将项目设置为使用UNICODE来实现)。这也使得_T、TCHAR、_TEXT和TEXT宏自动变为L。这些都是特定于Microsoft的,因此,如果您想跨平台使用,请避免使用它们。

我建议您不要担心支持ascii和unicode构建(a-la TCHAR),直接使用unicode。这样,您就可以使用更多与平台无关的函数(wcscpy、wcsstr等),而不是依赖于Micrpsoft特定的
TCHAR
函数

您可以使用std::wstring代替std::string,并用
wchar\t
s替换所有
char
s。通过这样一个巨大的改变,我发现你从一件事开始,让编译器引导你去做下一件事

我能想到的一件事可能在运行时并不明显,那就是使用malloc分配字符串,而不对底层类型使用
sizeof
运算符。所以要注意像
char*p=(char*)malloc(11)
-10个字符加上终止NULL,这个字符串的大小将是
wchar\t
s中应该的大小的一半。它应该变成
wchar\u t*p=(wchar\u t*)malloc(11*sizeof(wchar\u t))

哦,整个
TCHAR
就是支持编译时ASCII/Unicode字符串。它的定义如下:

#ifdef _UNICODE
#define _T(x) L ## x
#else
#define _T(x) ## x
#endif

因此,在unicode配置中,
变成
L“blah”
,在ascii配置中,它是
“blah”

L”“
std::wstring
(后者不是多平台的)和Microsoft关于如何使用unicode的建议,我非常反对

在这个问题上有很多困惑。有些人仍然认为Unicode==2字节字符==UTF-16。两种平等都不正确

事实上,使用char*和普通的
std::string
、普通的文本和很少的更改(仍然完全支持Unicode!)是可能的,甚至更好


请看我的答案:如何以最简单的方式(在我看来)解决问题。

你的问题涉及两个不同但相关的概念。其中之一是字符串的编码(例如Unicode/ASCII)。另一个是用于字符表示的数据类型

从技术上讲,可以使用纯
char
和std::string创建Unicode应用程序。您可以使用十六进制(“\x5FA”)或八进制(\05FA”)格式的文字来指定字符串的字节序列。请注意,使用这种方法,您已经存在的包含ASCII字符的字符串文本应该保持有效,因为Unicode保留ASCII中的代码

需要注意的一点是,许多与字符串相关的函数都需要小心使用。这是因为它们将在字节上操作,而不是在字符上操作。例如,
std::string::operator[]
可能会为您提供一个特定字节,该字节只是Unicode字符的一部分

在Visual Studio中,选择了
wchar\u t
作为基础字符类型。因此,如果您与基于Microsoft的图书馆合作,如果您遵循此处其他人发布的许多建议,事情会变得更容易。使用“t”宏(如果希望在Unicode/非Unicode之间保持透明度)等替换
wchar\u t
char

但是,我认为没有跨库使用Unicode的实际标准,因为它们可能有不同的策略来处理它。

注意:哇。。。显然,有人认为几乎所有的答案都值得一个downmod,即使是正确的。。。我承担起升级它们的责任,以平衡下行模式

让我们看看我是否有自己的downmod…:-/

编辑:高兴!!! 九小时前,有人(可能是那个否决了所有答案的人,但帕维尔·拉齐维洛夫斯基的答案除外)否决了这个答案。当然,没有任何评论指出我的答案有什么问题

\o/

1-如何在Windows Unicode上迁移? 为了迁移此代码,使其在VisualStudio的生态系统中工作,我需要做哪些更改
namespace std
{

#ifdef _MSC_VER

#ifdef UNICODE
typedef             wstring                         tstring ;
typedef             wistream                        tistream ;
// etc.
#else // Not UNICODE
typedef             string                          tstring ;
typedef             istream                         tistream ;
// etc.
#endif

#endif

} // namespace std
#ifdef __GNUC__

#ifdef  __cplusplus
extern "C" {
#endif

#define _TEOF       EOF

#define __T(x)      x

// etc.
#define _tmain      main

// etc.

#define _tprintf    printf
#define _ftprintf   fprintf

// etc.

#define _T(x)       __T(x)
#define _TEXT(x)    __T(x)

#ifdef  __cplusplus
}
#endif

#endif // __GNUC__
namespace std
{

#ifdef _MSC_VER

#ifdef UNICODE
typedef             wstring                         tstring ;
typedef             wistream                        tistream ;
// etc.
#else // Not UNICODE
typedef             string                          tstring ;
typedef             istream                         tistream ;
// etc.
#endif

#elif defined(__GNUC__)
typedef             string                          tstring ;
typedef             istream                         tistream ;
// etc.
#endif

} // namespace std