Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.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++ 打印std::string的字节表示形式_C++_Std - Fatal编程技术网

C++ 打印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::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]) << " ";
}
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
平台时注意到问题。