在 Unicode 到 ASCII 转换后声明 std::string 会出现分段错误
Declaring a std::string after Unicode to ASCII conversion is giving Segmentation fault
我正在尝试从 stdin 获取一个 wchar_t
字符串,然后通过函数将其从 unicode 转换为 ASCII。
该函数以某种方式不允许我在程序中进一步使用 std::string。
#include <iostream>
#include <string>
#include <locale>
#include <cstring>
#include <cwchar>
using namespace std;
bool UnicodeToAscii(wchar_t* szUnicode, char* szAscii);
int main()
{
wchar_t w[100];
wcin>>w;
char* c;
bool x=UnicodeToAscii(w,c);
cout<<c<<"\n";
string s="hi";
return 0;
}
bool UnicodeToAscii(wchar_t* szUnicode, char* szAscii)
{
int len, i;
if((szUnicode == NULL) || (szAscii == NULL))
return false;
len = wcslen(szUnicode);
for(i=0;i<len+1;i++)
*szAscii++ = static_cast<char>(*szUnicode++);
return true;
}
- 在写入无效指针之前,您永远不会为
c
分配内存。
cin >>
到固定大小的数组是不安全的。您可以考虑 std::wstring
.
- 如果要将 16 位字符转换为 8 位字符,请在 8 位字符串中使用 UTF-8 编码,而不是 ASCII。如果你必须使用 ASCII,如果任何字符超出范围,你将不得不出错,或者用占位符替换它。但是,这会使您得不到国际支持。您应该能够轻松找到有关在 C++ 中将 UTF-16 转换为 UTF-8 的信息。
您没有为 c
分配任何内存,因此您正在将字符数据写入随机内存并破坏您的程序。
您应该停止使用字符数组和原始指针,而开始使用 std::string
和 std::wstring
。让他们为您管理内存。
试试这个:
#include <iostream>
#include <string>
void UnicodeToAscii(const std::wstring &szUnicode, std::string &szAscii);
int main()
{
std::wstring w;
std::wcin >> w; // or std::getline(wcin, w);
std::string c;
bool x = UnicodeToAscii(w, c);
std::cout << c << "\n";
std::string s = "hi";
return 0;
}
void UnicodeToAscii(const std::wstring &szUnicode, std::string &szAscii)
{
szAscii.clear(len);
int len = szUnicode.length();
char c;
szAscii.reserve(len);
for(int i = 0; i < len; ++i)
{
wchar_t w = szUnicode[i];
if ((w >= 0) && (w < 127))
{
// ASCII character
c = static_cast<char>(w);
}
else
{
// non-ASCII character
c = '?';
// wchar_t is 2 bytes (UTF-16) on some systems,
// but is 4 bytes (UTF-32) on other systems...
#if sizeof(wchar_t) == 2
if ((w >= 0xD800) && (w <= 0xDFFF))
{
// skip first unit of a surrogate pair,
// the loop will skip the second unit...
++i;
}
#endif
}
szAscii.push_back(c);
}
return true;
}
当然,这是非常初级的,它只处理真正的 ASCII 字符 (0x00 - 0x7F)。正确处理 Unicode 比这复杂得多。但这回答了您关于为什么在调用函数后不能使用 std::string
的直接问题 - 因为您正在浪费内存。
我正在尝试从 stdin 获取一个 wchar_t
字符串,然后通过函数将其从 unicode 转换为 ASCII。
该函数以某种方式不允许我在程序中进一步使用 std::string。
#include <iostream>
#include <string>
#include <locale>
#include <cstring>
#include <cwchar>
using namespace std;
bool UnicodeToAscii(wchar_t* szUnicode, char* szAscii);
int main()
{
wchar_t w[100];
wcin>>w;
char* c;
bool x=UnicodeToAscii(w,c);
cout<<c<<"\n";
string s="hi";
return 0;
}
bool UnicodeToAscii(wchar_t* szUnicode, char* szAscii)
{
int len, i;
if((szUnicode == NULL) || (szAscii == NULL))
return false;
len = wcslen(szUnicode);
for(i=0;i<len+1;i++)
*szAscii++ = static_cast<char>(*szUnicode++);
return true;
}
- 在写入无效指针之前,您永远不会为
c
分配内存。 cin >>
到固定大小的数组是不安全的。您可以考虑std::wstring
.- 如果要将 16 位字符转换为 8 位字符,请在 8 位字符串中使用 UTF-8 编码,而不是 ASCII。如果你必须使用 ASCII,如果任何字符超出范围,你将不得不出错,或者用占位符替换它。但是,这会使您得不到国际支持。您应该能够轻松找到有关在 C++ 中将 UTF-16 转换为 UTF-8 的信息。
您没有为 c
分配任何内存,因此您正在将字符数据写入随机内存并破坏您的程序。
您应该停止使用字符数组和原始指针,而开始使用 std::string
和 std::wstring
。让他们为您管理内存。
试试这个:
#include <iostream>
#include <string>
void UnicodeToAscii(const std::wstring &szUnicode, std::string &szAscii);
int main()
{
std::wstring w;
std::wcin >> w; // or std::getline(wcin, w);
std::string c;
bool x = UnicodeToAscii(w, c);
std::cout << c << "\n";
std::string s = "hi";
return 0;
}
void UnicodeToAscii(const std::wstring &szUnicode, std::string &szAscii)
{
szAscii.clear(len);
int len = szUnicode.length();
char c;
szAscii.reserve(len);
for(int i = 0; i < len; ++i)
{
wchar_t w = szUnicode[i];
if ((w >= 0) && (w < 127))
{
// ASCII character
c = static_cast<char>(w);
}
else
{
// non-ASCII character
c = '?';
// wchar_t is 2 bytes (UTF-16) on some systems,
// but is 4 bytes (UTF-32) on other systems...
#if sizeof(wchar_t) == 2
if ((w >= 0xD800) && (w <= 0xDFFF))
{
// skip first unit of a surrogate pair,
// the loop will skip the second unit...
++i;
}
#endif
}
szAscii.push_back(c);
}
return true;
}
当然,这是非常初级的,它只处理真正的 ASCII 字符 (0x00 - 0x7F)。正确处理 Unicode 比这复杂得多。但这回答了您关于为什么在调用函数后不能使用 std::string
的直接问题 - 因为您正在浪费内存。