硬编码字符串与强制转换为 PUCHAR 并打印到控制台时从控制台读取的字符串的结果不同



我完全被迷惑了。我一直在寻找几个小时,为什么我无法将字符串转换为 PUCHAR(无符号字符*(。这很奇怪,但出于某种原因,Windows 加密方法只接受 PUCHAR 的......(为什么?

我找到了很多解决方案,但起初它们似乎不起作用。ASCII 表中的前 128 个字符工作正常,但其他字符(如"ù"和"μ"(被转换为其他字符(主要是奇怪的 ASCII 符号,但相应的给定字符总是相同的符号(。

我现在刚刚发现强制转换确实有效,但仅适用于使用 cin 从控制台读取的字符串?!硬编码字符串不起作用?!老实说,我对这种行为的原因一无所知。

下面是一个示例:

使用CIN

cout << "With cin: ";
string password;
cin >> password;
unsigned char q = (unsigned char)password[0];
PUCHAR pbPassword = new unsigned char[1];      
pbPassword[0] = q;
pbPassword[1] = NULL;                       //Null or garbage is printed
cout << pbPassword;

这输出:

与 cin:

µ
µ

无CIN代码

cout << "Without cin: ";
string password = "µ";
unsigned char q = (unsigned char)password[0];
PUCHAR pbPassword = new unsigned char[1];
pbPassword[0] = q;
pbPassword[1] = NULL;
cout << pbPassword;

这输出:

Without cin: ╡

我是一名初级程序员,如果代码混乱,很抱歉。

尽管我使用相同的字符,但硬编码字符串的强制转换不起作用。即使使用完全相同的铸件。

我还注意到,我可以将一个字符放在索引 1 处,而数组的长度只有 1,这意味着我正在访问我实际上不应该访问的内存。这怎么可能?通常这会导致某种内存访问错误,对吗?

编辑:主要问题不是如何投射,或者为什么即使长度为1,我仍然可以将元素放入数组中。这就是为什么 cout 为从 cin 读取的字符串和硬编码字符串的强制转换给出不同的结果。

字符串文本可能编码在保存源文件的任何代码页中。打印这些字符串时,它们将显示在控制台的代码页中。

从控制台读取的字符串将位于控制台的代码页中,因此在发送回控制台时将正确打印。

在 Windows 上,如果要在控制台上读取或写入非 ASCII 字符,则应使用std::wcinstd::wcoutstd::wstring以避免此问题。然后,如果需要,可以将std::wstring转换为 utf-8 或 1 字节代码页之一。

使用new unsigned char[1],您可以分配一个unsigned char。然后你执行pbPassword[1] = NULL这将索引超出界限并导致未定义的行为

分配中的数字不是顶部索引,而是元素的数量,就像声明数组时一样。所以它应该是new unsigned char[2].

即使你需要传递指向某处unsigned char的指针,我建议你仍然使用std::string。这意味着你应该有

std::string pbPassword(1, password[0]);

这将创建一个带有一个字符的字符串,并将其初始化为password[0]。如果你需要从中PUCHAR,你可以投射它:

reinterpret_cast<const PUCHAR>(pbPassword.c_str())

对于"没有cin"的情况,它看起来像编码不匹配。 首先读取 1 字节 0xB5(181( (什么是 password.size(( ?(,然后使用默认代码页 437 将其打印到控制台,其中 181 是 ╡ 的代码。

最新更新