ISO-8859-5标准是unicode字符集的子集。我想测试C ++中ISO-8859-5的字符子集是否支持unicode字符。为此,我想在下面编写一个类似 isLegal 的函数,以便下面的代码将过滤掉非ISO-8859-5字符。
假设wstring来自unicode编码的字符串。
wstring str = L"AåБ0";
vector<char32_t> bytes(str.begin(), str.end());
for (vector<char32_t>::const_iterator i = bytes.begin(); i != bytes.end(); ++i){
if (isLegal(*i, "ISO-8859-5"))
{
std::cout << (*i) << ' ';
}
}
原因是我希望将支持的字符限制为unicode超集的子集,以便用户无法提交表情符号等字符以及不支持的语言字符。谢谢你的帮助。
有一种简单的方法可以做到这一点。使用例如编解码器或类似的东西。例如,我知道Qt的一个函数是否有任何东西可以帮助我?
QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5");
也许是一个可以为我做这件事的图书馆。
注意:为什么我使用wstring?我的理解是unicode字符每个字符使用1到4个字节。这是字符的二进制表示形式,与呈现字符时不同。 std:string支持多字节字符串,但是当你尝试隔离单个字符时,我不知道字符的起始位置和结束位置,因为每个字符的字节宽度不一致。
所以我使用编解码器将多字节字符串解码为std :: wstring,这是在wchar_t上模板化的。 Linux上的wchar_t是4个字节宽,因此每个字符的宽度都是一致的。因此,如果将多字节unicode设置为wstring,则可以更轻松地识别每个字符,因为每个字符的宽度一致为4个字节,并且所有unicode字符都适合4位宽度,因此wstring处理来自任何可能的字符的unicode。
答案 0 :(得分:0)
没有用于字符代码转换的标准C ++库。实际上,我认为C ++实现甚至不需要知道多个编码。所以任何解决方案都需要一个库,或者手工制作的代码(即大switch
...)。
既然你提到Qt,那么是的,你应该可以使用QTextCodec::canEncode
:
#include <QDebug>
#include <QTextCodec>
#include <string>
int main() {
std::wstring const str = L"AåБ0";
auto const *codec = QTextCodec::codecForName("ISO-8859-5");
if (!codec) {
qFatal("Codec not found");
}
qDebug() << "Using codec" << qPrintable(codec->name());
for (auto c: str) {
if (codec->canEncode(c))
qDebug() << c;
}
}
但是这给了我
Using codec ISO-8859-5
65
229
1041
128512
128580
128545
48
所以这是一个非解决方案。
答案 1 :(得分:0)
目前我正在使用此自定义解决方案:
#include <vector>
#include <string>
#include <boost/assign/std/vector.hpp>
using namespace std;
using namespace boost::assign;
bool isIntInSet(int val, std::vector<int> set){
if (std::find(set.begin(), set.end(), val) != set.end())
{
return true;
}
return false;
}
bool isLegal(int val, string isoNum){
const string ISO8859_5 = "ISO8859-5";
if (ISO8859_5 == isoNum){
vector<int> isoSet5;
isoSet5 += 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x00A0,0x0401,0x0402,0x0403,0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040A,0x040B,0x040C,0x00AD,0x040E,0x040F,0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F,0x2116,0x0451,0x0452,0x0453,0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045A,0x045B,0x045C,0x00A7,0x045E,0x045F;
if (isIntInSet(val, isoSet5))return true;
}
return false;
}
通过在http://czyborra.com/charsets/iso8859.html上查找可见字符集列表,每个字符集都不包含控制字符,因此这不是完整的ISO8859-5字符列表,但对所有可打印字符来说似乎都足够好。