所以,我正在构建脚本语言,我的目标之一是方便的字符串操作。我在C ++中尝试了一些想法。
这两个想法都有问题,那个问题是,我该怎么回事。它不可能是一个字符,如果它是一个字符串,那将是浪费的空间。
我最终围绕一个恰好4个字节的char数组创建了一个包装类:一个在内存中只有4个字节的字符串,不多也不少。
创建这个类之后,我觉得很想把它包装在另一个类的std::vector
中并从那里构建,从而形成一个字符串类型的代码点。我不知道这是不是一个好方法,它最终会更方便,但最终会浪费更多空间。
所以,在发布一些代码之前,这里有一个更有条理的想法列表。
mysring[0].is_whitespace()
我的代码:
class rune {
char data[4] {};
public:
rune(char c) {
data[0] = c;
}
// This constructor needs a string, a position and an offset!
rune(std::string const & s, size_t p, size_t n) {
for (size_t i = 0; i < n; ++i) {
data[i] = s[p + i];
}
}
void swap(rune & other) {
rune t = *this;
*this = other;
other = t;
}
// Output as UTF8!
friend std::ostream & operator <<(std::ostream & output, rune input) {
for (size_t i = 0; i < 4; ++i) {
if (input.data[i] == '\0') {
return output;
}
output << input.data[i];
}
return output;
}
};
错误处理想法:
我不喜欢在C ++中使用异常。我的想法是,如果构造函数失败,则将符文初始化为4 '\0'
,然后显式重载bool运算符,如果运行的第一个字节恰好是'\0'
则返回false。简单易用。
那么,想法?意见?不同的方法?
即使我的符文字符串很多,至少我有一个符文类型。小而快速复制。 :)
答案 0 :(得分:0)
听起来你正试图重新发明轮子。
当然,您需要考虑两种方式来考虑文本:
在某些代码库中,这两个表示形式是相同的(并且所有编码基本上都是char32_t
或unsigned int
的数组)。在一些(我倾向于说“最”但不引用我),编码的字节数组将使用UTF-8,其中代码点在被放入数据结构之前被转换为可变长度的字节
当然,许多代码库完全忽略unicode并将其数据存储在ASCII中。我不推荐。
出于您的目的,虽然编写一个类来“包裹”您的数据是有意义的(虽然我不会将其称为rune
,但我可能只称它为codepoint
}),你会想到你的语义。
std::string
视为UTF-8编码字符串,并将此作为处理文字的默认界面。对于大多数外部接口来说是安全的 - 唯一一次失败就是在与UTF-16输入接口时,你可以为它编写极端情况 - 它将为你节省大部分内存,同时仍然遵守常见的字符串约定(它是按字典顺序可比,这是最大的一个。)。codepoint
的结构(或类),其中包含以下有用的函数和构造函数
代码:
struct codepoint {
char32_t val;
codepoint(char32_t _val = 0) : val(_val) {}
codepoint(std::string const& s);
codepoint(std::string::const_iterator begin, std::string::const_iterator end);
//I don't know the UTF-8→codepoint conversion off-hand. There are lots of places
//online that show how to do this
std::string to_utf8() const;
//Again, look up an algorithm. They're not *too* complicated.
void append_to_string_as_utf8(std::string & s) const;
//This might be more performant if you're trying to reduce how many dynamic memory
//allocations you're making.
//codepoint(std::wstring const& s);
//std::wstring to_utf16() const;
//void append_to_string_as_utf16(std::wstring & s) const;
//Anything else you need, equality operator, comparison operator, etc.
};