首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ WCHAR操作

C++ WCHAR操作
EN

Stack Overflow用户
提问于 2012-11-13 19:48:19
回答 3查看 19.9K关注 0票数 6

我正在用C++开发一个很小的Win32应用。我很久以前就学习过C++的基础知识,所以现在我对C++中的字符串完全迷惑了。没有WCHARTCHAR,只有charString。经过一些调查之后,我决定不使用TCHAR

我想我的问题很简单,但是我找不到明确的指南如何在C++中操作字符串。过去几年受PHP编码的影响,我一直期望能有一些简单的字符串操作,但我错了!

简单地说,我所需要的就是将新数据放到一个字符串中。

代码语言:javascript
复制
    WCHAR* cs = L"\0";
    swprintf( cs, "NEW DATA" );

这是我第一次尝试。在调试我的应用程序时,我发现swprintf只将前2个字符放到了我的cs变量中。我已经这样解决了我的问题:

代码语言:javascript
复制
    WCHAR cs[1000];
    swprintf( cs, "NEW DATA" );

但通常这种技巧可能会失败,因为在我的例子中,新数据不是常量值,而是另一个变量,它可能比1000个字符的长度更宽。我的代码是这样的:

代码语言:javascript
复制
    WCHAR cs[1000];
    WCHAR* nd1;
    WCHAR* nd2;
    wcscpy(nd1, L"Some value");
    wcscpy(nd2, L"Another value"); // Actually these vars stores the path for user selected folder
    swprintf( cs, "The paths are %s and %s", nd1, nd2);

在这种情况下,nd1和nd2的字符总数有可能超过1000个字符,因此关键数据将会丢失。

问题是,如何才能将所有需要的数据复制到以这种方式声明为WCHAR* wchar_var;的WCHAR string中,而不会丢失任何内容?

另外,由于我是俄罗斯人,这个问题可能不清楚。现在让我谈谈这一点,我会试着更清晰、更复杂地解释我的问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-13 19:58:04

在现代Windows编程中,可以忽略TCHAR,转而使用wchar_t (WCHAR)和Unicode UTF-16。

(TCHAR是一种过去的模型,当您想要只有一个代码库,并同时生成ANSI和Unicode构建时,需要更改一些预处理器开关,如_UNICODEUNICODE。)

在任何情况下,都应该使用C++和方便的字符串类来简化代码。您可以使用ATL::CString (对应于Unicode构建中的CStringW,这是自VS2005以来的默认设置)或STL的std::wstring

使用CString,您可以执行以下操作:

代码语言:javascript
复制
CString str1 = L"Some value";
CString str2 = L"Another value";
CString cs;
cs.Format(L"The paths are %s and %s", str1.GetString(), str2.GetString());

CString还提供了适当的operator+重载来连接字符串(这样您就不必计算结果字符串的总长度、为目标字符串动态分配缓冲区或检查现有缓冲区大小、调用wcscpywcscat、不要忘记释放缓冲区等)。

您可以简单地将CString实例传递给需要const wchar_t* (LPCWSTR/PCWSTR)参数的Win32 API,因为CString提供了到const wchar_t*的隐式转换操作符。

票数 7
EN

Stack Overflow用户

发布于 2012-11-13 19:57:51

当您使用WCHAR*时,您正在调用未定义的行为,因为您有一个指针,但没有使它指向任何有效的指针。您需要找出结果字符串的长度,并为该字符串动态分配空间。例如:

代码语言:javascript
复制
WCHAR* cs;
WCHAR* nd1;
WCHAR* nd2;

nd1 = new WCHAR[lstrlen(L"Some value") + 1]; // +1 for the null terminator
nd2 = new WCHAR[lstrlen(L"Another value") + 1];
cs = new WCHAR[lstrlen(L"The paths are  and ") + lstrlen(nd1) + lstrlen(nd2) + 1];

wcscpy(nd1, L"Some value");
wcscpy(nd2, L"Another value"); // Actually these vars stores the path for user selected folder
swprintf( cs, L"The paths are %s and %s", nd1, nd2);

delete[] nd1;
delete[] nd2;
delete[] cs;

但这是非常丑陋和容易出错的。如前所述,您应该改用std::wstring,如下所示:

代码语言:javascript
复制
std::wstring cs;
std::wstring nd1;
std::wstring nd2;

nd1 = L"Some value";
nd2 = L"Another value";
cs = std::wstring(L"The paths are ") + nd1 + L" and " + nd2;
票数 2
EN

Stack Overflow用户

发布于 2012-11-13 20:10:49

建议使用ATL CStringW类来代替原始的WCHAR,这样更方便。CString是动态分配的C字符串的包装器。它将在每个操作之后适当地管理字符串长度和分配的内存缓冲区,所以你不会关心它。

典型用法:

代码语言:javascript
复制
#include <atlstr.h>

CStringW s;
s.Format(L"The paths are %s and %s", L"Some value", L"Another value");
const WCHAR* wstr = s.GetString(); // To pass to some API that need WCHAR

代码语言:javascript
复制
#include <atlstr.h>

CStringW s(L"The paths are ");
s += L"Some value";
s += L" and ";
s += L"Another value";
const WCHAR* wstr = s.GetString(); // To pass to some API that need WCHAR
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13360228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档