我正在用c ++教我自己的WinAPI,但随着我的进步,我注意到WinAPI中的每个函数都返回char *,DWORD,LPCSTR等。我担心的是我喜欢使用字符串,所以我在做什么呢我得到了将其转换为字符串的返回值。是好还是坏?或者如果我每次都转换它会有什么不同吗?或者它会使过程变慢或任何不好的东西。对于c ++中的I / O,考虑到exe的大小或性能/功能问题,什么是更好的cout或printf?
答案 0 :(得分:2)
首先学习各种字符串类型。例如,char*
,LPSTR
和LPCSTR
都是相关的并存储ANSI字符;最后一个是指向const字符串的指针。同样,wchar_t*
,WCHAR*
,LPWSTR
和LPCWSTR
都是相关的并存储Unicode字符;最后一个是指向const字符串的指针。
当你说“返回char *”之类的内容时,请注意你的意思,因为大多数Windows API都没有这样做。相反,它们采用LPSTR
(指向char缓冲区的指针)或LPWSTR
(指向WCHAR缓冲区的指针),并写入缓冲区。这些API几乎总是要么计算缓冲区中可用的字符数,要么具有记录的缓冲区大小要求,例如MAX_PATH
。
您可以利用此优势。 C ++ 11要求std::wstring
或std::string
连续存储其字符,并且所有已知的实现在此之前都做得很好。因此,给定像GetEnvironmentVariable这样的API,您可以直接使用字符串作为缓冲区并避开大多数转换。使用与此类似的代码,但随时可以修改它与代码其余部分的交互方式:
std::wstring GetEnvironmentVariable(const std::wstring& strName)
{
DWORD cchValue = MAX_PATH;
std::wstring strValue;
// call API once or twice, to get required buffer size
strValue.resize(cchValue);
cchValue = GetEnvironmentVariable(strName.c_str(), &strValue[0], cchValue);
if (cchValue > MAX_PATH)
{
strValue.resize(cchValue);
cchValue = GetEnvironmentVariable(strName.c_str(), &strValue[0], cchValue);
}
// process errors such as ERROR_ENVVAR_NOT_FOUND
if (0 == cchValue)
{
// throw exception? return empty string? (current code does latter)
}
// remove null character and any extra buffer
strValue.resize(cchValue);
return strValue;
}
您可以对此方法进行大量进一步的改进。
LPTSTR
来创建一个typedef tstring
,根据定义创建映射到std::wstring
或std::string
的{{1}} UNICODE
的{{1}}(否则我建议只做我上面所示的宽字符串)。您可以执行在C ++中重载的显式A和W函数调用,或遵循Windows命名约定。就I / O而言,没有一个明显的赢家。你会发现在Windows中使用控制台和控制台I / O是相当罕见的,所以也许这个问题毕竟不是很有趣。除此之外,在国际化方面存在重大权衡;即翻译完整的句子格式字符串比翻译因使用iostream而产生的片段要容易得多。但如果翻译不是你的问题,那不会影响你的决定。
答案 1 :(得分:1)
您提出的几乎所有内容都是基于意见的。是的,将你得到的每个字符*转换为std :: string会比较慢,但不会产生太大影响。当然,这完全取决于你经常这样做,以及你将在哪里运行这个程序。在这种情况下将事物转换为std :: string绝对没有问题,但是要注意,你不会有一个有趣的时间来对抗任何API(转换为所有类型的转换将会更加繁琐时间。)最后,这完全取决于你。请记住,仅仅因为您将使用new或malloc分配的char *转换为std :: string并不意味着您不必释放或删除它。
我没有看到printf或std :: cout的问题。再一次,这完全是基于意见的。但是,std :: cout可能更容易使用,并且当然更加类型安全。