我试图编写从istream中读取字符并将其转换为wchar_t的小程序。我得到了一个段错误。这是我的代码
#include <iostream>
using namespace std;
wchar_t read(istream &stream) {
char *c;
stream.read(c, sizeof(*c));
cout << *c << endl;
wchar_t retChar = static_cast<wchar_t>(*c);
return retChar;
}
int main() {
cout << "Write something" << endl;
read(cin);
}
我的逻辑是:
由于我遇到了段错误,所以这里显然有些不对劲。但我无法看到它。任何帮助将不胜感激。
非常感谢
答案 0 :(得分:1)
逐步完成代码,让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&#39;和ASCII编码到retChar
。 retChar
现在等于65. 65可能意味着取决于wchar_t
使用的编码。它可能仍然意味着A&#39;但对不起Ayn Rand,这是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;
Null终止并打印。
wchar_t retChar[2];
再次,一个数组。
mbstowcs(retChar, c, 1);
使用已设置的任何语言环境将一个字符从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.