通过代码步进给OP看看发生了什么事情,为什么它不会工作。然后,我们将看看一种方法,尽可能接近他们的意图。然后提示如何在C++世界中更好地实现这一点。
wchar_t read(istream &stream) {
char *c;
声明一个指针c
,并在任何不点它。 c
是一个未初始化的变量。想想就像被邀请到史蒂夫的家里参加派对,但没有人告诉你他住在哪里。无论你走到哪里,赔率都非常好,它不会是史蒂夫的家。
stream.read(c, sizeof(*c));
sizeof(*c)
将返回一个字符的大小。大概8位和1个字节,但c
仍然没有指向任何东西,所以这是Undefined Behaviour。不知道程序会做什么,但很可能它会在内存中的某个未知空间中读取一个字节。也许这会导致崩溃,因为你不能在那里写。也许它写了一些东西,它允许写下来,并拧紧其他东西。
cout << *c << endl;
试图打印出c
。如果程序在上面的read
中幸存下来,那么赔率很好,它也能保存下来,但这也是未定义的行为。
wchar_t retChar = static_cast<wchar_t>(*c);
这将从字面上将一个字符的数据填充到宽字符中。它不会根据语言环境或任何其他字符编码进行转换。 char
是一个数字代码,已被定义为被解释为一个字符。演员会愚蠢地把字符值,如'A'和ASCII编码放入retChar
。 retChar
现在等于65. 65可能意味着任何取决于wchar_t
使用的编码。它可能仍然意味着“A”,但遗憾兰德,这是一个情况下一个很可能不是A.
return retChar;
}
要做些什么OP试图做(和忽略有更好的方法做这是暂时的):
#include <iostream>
using namespace std;
wchar_t read(istream &stream) {
char c[2];
分配一个字符数组。为什么?因为我知道的最简单的方法是对字符串进行转换。
stream.read(c, sizeof(c[0]));
c
现在是一个衰减为指针的数组。我们只想读取一个char
,因此sizeof(c[0])
获取数组中第一个元素的大小。
c[1] = '\0';
cout << c << endl;
无效终止并打印。
wchar_t retChar[2];
再次,一个数组。
mbstowcs(retChar, c, 1);
使用设置的任何语言环境将一个字符从char转换为wide char。了解更多关于语言环境的位置:http://en.cppreference.com/w/cpp/locale/setlocale
和文件上mbstowcs:http://en.cppreference.com/w/cpp/string/multibyte/mbstowcs
return retChar[0];
}
一个快速测试仪放在一起:
#include <iostream>
#include <cstdlib>
wchar_t read(std::istream &stream)
{
char c[2];
stream.read(c, sizeof(c[0]));
c[1] = '\0';
std::cout << c << std::endl;
wchar_t retChar[2];
mbstowcs(retChar, c, 1);
return retChar[0];
}
int main()
{
std::wcout << read(std::cin) << std::endl;
}
这很简单,但丑陋在C++的世界里,在可能的情况下,您应该坚持使用string
。 In that case look into std::wstring_convert.
你永远不会为你的'char *'分配内存。比你没有真正转换任何东西 - 你只是在没有任何对话的情况下投射类型。 – SergeyA
您的segfault与转换为'wchar_t'无关。你得到的是因为你的'read'函数的前两行。你正在读入一个单元化的(无效的)指针(更不用说了 - 在同一行中解引用指针) –
你也可以声明你想要存储的东西,然后将其转换为调用中的char *到'read'。 – NathanOliver