要将std::string
分成字符,我可以遍历字符串。但是,如果字符串包含德语变音符号ä,ö,ü,ß,...
,则此方法不起作用。
我找到了一个适用于我的使用std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>
的解决方案。但这感觉太复杂了,有更好的解决方案吗?
#include <string>
#include <vector>
#include <iostream>
#include <locale>
#include <codecvt>
// Works with umlauts:
std::vector<std::string> split_wstring(const std::string &word) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wword = converter.from_bytes(word);
std::vector<std::string> characters;
for (auto iter : wword) {
characters.push_back(converter.to_bytes(iter));
}
return characters;
}
// Works fine for english words but fails for umlauts:
std::vector<std::string> split_string(const std::string &word) {
std::vector<std::string> characters;
for (auto iter : word) {
characters.push_back(&iter);
}
return characters;
}
int main() {
for (auto c : split_string("AbcühßtÖ")) {
std::cout << "Split String: " << c << std::endl;
}
for (auto c : split_wstring("AbcühßtÖ")) {
std::cout << "Split W-String: " << c << std::endl;
}
}
(我将单词分割为长度为1的std :: string而不是char,因为无论如何我都需要将它们设为std :: strings)
输出为:
Split String: A
Split String: b
Split String: c
Split String: �
Split String: �
Split String: h
Split String: �
Split String: �
Split String: t
Split String: �
Split String: �
Split W-String: A
Split W-String: b
Split W-String: c
Split W-String: ü
Split W-String: h
Split W-String: ß
Split W-String: t
Split W-String: Ö
有类似的帖子:Update by query API 解决方案是使用冗长的第三方代码。我认为wstring转换器的解决方案已经更好了。
答案 0 :(得分:0)
感谢所有答复,他们帮助我理解了转换为Utf-16或Utf-32并不是最好的方法。
我再次查看了this answer,并基于它编写了一个迭代器。我可以确认它适用于字符长度不同的utf-8字符串。
#include <string>
#include <vector>
#include <iostream>
class UtfIterator {
public:
std::string::const_iterator str_iter;
size_t cplen;
UtfIterator(const std::string::const_iterator str_iter) : str_iter(str_iter) {
find_cplen();
}
std::string operator*() const {
return std::string(str_iter, str_iter + cplen);
}
UtfIterator& operator++() {
str_iter += cplen;
find_cplen();
return *this;
}
bool operator!=(const UtfIterator &o) const {
return this->str_iter != o.str_iter;
}
private:
void find_cplen() {
cplen = 1;
if((*str_iter & 0xf8) == 0xf0) cplen = 4;
else if((*str_iter & 0xf0) == 0xe0) cplen = 3;
else if((*str_iter & 0xe0) == 0xc0) cplen = 2;
// if(iter + cplen > text.length()) cplen = 1;
}
};
int main() {
std::string s("今天周五123äöÜß");
for (UtfIterator iter(s.begin()); iter != UtfIterator(s.end()); ++iter) {
std::cout << "char: " << *iter << std::endl;
}
}
关于那条未注释的行:据我所知,它的目的是查找损坏的Utf-8字符串,这些字符串最后缺少字节。在不知道end()
迭代器的情况下,我找不到在迭代器中实现此方法的方法。有什么想法吗?