我正在编写一个小程序,从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);
}
我的逻辑是:
既然我有段错,这里显然出了点问题。不过我看不见。任何帮助都将不胜感激。
谢谢你
发布于 2016-03-07 12:45:36
通过遍历代码,让OP了解发生了什么,以及为什么它不能工作。然后,我们将看一个方法来做他们想做的,这是尽可能接近他们的意图。然后介绍一下如何在C++世界中更好地做到这一点。
wchar_t read(istream &stream) {
char *c;
声明一个指针c
,它没有指向任何东西。c
是一个未初始化的变量。想想看,就像被邀请去史蒂夫家参加聚会一样,但没人告诉你他住在哪里。不管你去哪里,它都不会是史蒂夫的家,这是很好的。
stream.read(c, sizeof(*c));
sizeof(*c)
将返回一个字符的大小。可能是8位1字节,但c
仍然没有指向任何东西,所以这是未定义行为。不知道程序将做什么,但很可能它会将一个字节读入内存中的某个未知空间。也许这会导致崩溃,因为你不能在那里写字。也许它写的东西,它被允许写下来,并搞砸了其他的东西。
cout << *c << endl;
试图打印出c
。如果程序在上面的read
中幸存下来,几率是很好的--它也能存活下来,但这也是不确定的行为。
wchar_t retChar = static_cast<wchar_t>(*c);
这实际上会将一个字符的价值数据填充到一个宽字符中。它不会根据地区或任何其他字符编码来转换它。char
是被定义为字符的数字代码。一个演员会愚蠢地将字符值,例如'A‘和ASCII编码到retChar
中。retChar
现在等于65。65可能意味着任何东西,这取决于wchar_t
使用的编码。它的意思可能仍然是' A ',但对不起,艾恩兰德,这是一个情况下,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);
使用已设置的任何区域设置将一个字符从字符转换为宽字符。在这里阅读更多关于地区的信息: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
。皈依。
https://stackoverflow.com/questions/35852656
复制相似问题