C++ 打印std::string的字节表示形式
当std::wstring正常工作时,我在打印std::string的字节表示时遇到了奇怪的错误C++ 打印std::string的字节表示形式,c++,std,C++,Std,当std::wstring正常工作时,我在打印std::string的字节表示时遇到了奇怪的错误 std::string str = "mystring"; unsigned short* vtemp = (unsigned short*)str.c_str(); for(int i=0; i<str.length(); ++i) { cout << (unsigned short)((unsigned char)vtemp[i]) << " "; } co
std::string str = "mystring";
unsigned short* vtemp = (unsigned short*)str.c_str();
for(int i=0; i<str.length(); ++i)
{
cout << (unsigned short)((unsigned char)vtemp[i]) << " ";
}
cout << endl;
Incorrect Output: 109 115 114 110 0 204 204 204
wstring wstr(str.length(), L' ');
std::copy(str.begin(), str.end(), wstr.begin());
vtemp = (unsigned short*)wstr.c_str();
for(int i=0; i<wstr.length(); ++i)
{
cout << (unsigned short)((unsigned char)vtemp[i]) << " ";
}
cout << endl;
Correct Output: 109 121 115 116 114 105 110 103
std::string str=“mystring”;
无符号短*vtemp=(无符号短*)str.c_str();
对于(int i=0;i而言,问题在于您使用的是无符号短
指针,因此每个++i
都会将指针向前推进sizeof(无符号短)
字节。如果在您的平台上sizeof(无符号短)==2,第一个版本很可能会跳过其他字符。这是因为这一行:
unsigned short* vtemp = (unsigned short*)str.c_str();
unsigned short
的长度为两个字节。char
的长度为一个字节。您正在设置一个指向char
数组的unsigned short
指针,并通过指针索引(每两个字节)进行迭代
编译器通常会告诉您这一点,但使用C样式转换会阻止这一点(因为C样式转换会以静默方式失败)
稍后编辑:您的代码还对unsigned short*
进行索引,最多可索引str.length()
元素,但(short
大于char
)数组仅包含str.length()/2
unsigned short
可索引元素
在某些机器上运行该代码可能会导致内核转储
unsigned short* vtemp = (unsigned short*)str.c_str();
替换为:
unsigned char* vtemp = (unsigned char*)str.c_str();
wstring以两个字节的格式存储原始数据,而string以一个字节或简单的char格式存储原始数据。一旦执行(unsigned short*)str.c_str(),您就必须跳转两次而不是一次。在访问str的原始数据时,您必须使用char*(根据我的经验,即使是unsigned char*也会导致问题).所以正确的做法是
const char *vtemp = str.c_str();
const char*vtemp=str.c_str();
char是一个字节,我不明白为什么要将对c_str()的调用强制转换为一个无符号的short*
,其中一个原因是:返回值不是无符号的
(对于某些平台可能是,取决于编译器如何实现它),而对于第二个原因,为什么不暂时存储它返回的内容并用强制转换打印出来呢(查看它所代表的数字)
它之所以“跳过”,是因为正如我所说的std::string和std::wstring的定义如下:
std::string的定义:
typedef std::basic\u string std::string;
std::wstring的定义:
typedef std::basic\u string std::wstring;
如您所见,它们不是用无符号说明符定义的。对于std::string,c_str()返回一个const char*
,对于std::wstring,c_str()返回一个const wchar\u t*
因此,请尝试以下方法:
#include <iostream>
#include <string>
using namespace std;
int main()
{
std::string str = "mystring";
const char* vtemp = str.c_str();
for(int i=0; i<str.length(); ++i)
{
cout << (int)vtemp[i] << " ";
}
cout << endl;
wstring wstr(str.length(), L' ');
std::copy(str.begin(), str.end(), wstr.begin());
const wchar_t* wtemp = wstr.c_str();
for(int i=0; i<wstr.length(); ++i)
{
cout << (int)wtemp[i] << " ";
}
cout << endl;
}
#包括
#包括
使用名称空间std;
int main()
{
std::string str=“mystring”;
const char*vtemp=str.c_str();
对于(int i=0;你究竟想做什么?)首先,你不应该在C++中使用C风格的强制转换。
不会将static\u cast
转换为unsigned short*
,但需要重新解释\u cast
应该会提示您有问题。但是首先,std::string
可以使用迭代器进行迭代和索引;使用指针是完全多余的。啊!你说得对。我正在使用库函数需要以字符串形式传递的离子(unsigned short*),因此我想我必须使用wstring版本。(是的,segfault应为不正确的版本)@vivek.m:short
和wchar\u t
是不同的类型。形式上总是如此,但在某些系统上它们实际上大小不同。如果你有一个函数想要无符号short*
,它需要显式地utf-16
,你必须确保自己的格式正确!@JanHudec Correct。这是一个仅限windows的API和for windows,wstring将是utf-16。此外,我不知道任何简单的方法来确保wstring必须是utf-16…tx.“unsigned short
is two bytes long”不一定。标准上说的都是sizeof(unsigned short)>=signed(char)
@vivek。m:你不应该从任何地方得到非unicodewchar\u t
。因此基本平面(小于2^16的代码点)将始终正确。如果wchar\u t
为2字节(如在Windows中),则扩展平面(代码点2^16及以上)将不受支持或编码为utf-16
。如果wchar\u t
为4字节(如在Linux中),则扩展平面将直接编码(ucs-4
)我建议您添加一个转换例程,以便在尝试将代码移植到ucs-4
平台时注意到问题。