[英]C++ How to get first letter of wstring
这听起来像是一个简单的问题,但是C ++很难(至少对我而言):我有一个wstring,我想将第一个字母作为wchar_t对象,然后从字符串中删除该第一个字母。
这不适用于非ASCII字符:
wchar_t currentLetter = word.at(0);
因为它会返回两个字符(循环)以表示德语Umlauts等字符。
这在这里也不起作用:
wchar_t currentLetter = word.substr(0,1);
error: no viable conversion from 'std::basic_string<wchar_t>' to 'wchar_t'
而且也不是:
wchar_t currentLetter = word.substr(0,1).c_str();
error: cannot initialize a variable of type 'wchar_t' with an rvalue of type 'const wchar_t *'
还有其他想法吗?
干杯,
马丁
----更新-----这是一些可执行的代码,应演示该问题。 该程序将遍历所有字母,并将它们一个接一个地输出:
#include <iostream>
using namespace std;
int main() {
wstring word = L"für";
wcout << word << endl;
wcout << word.at(1) << " " << word[1] << " " << word.substr(1,1) << endl;
wchar_t currentLetter;
bool isLastLetter;
do {
isLastLetter = ( word.length() == 1 );
currentLetter = word.at(0);
wcout << L"Letter: " << currentLetter << endl;
word = word.substr(1, word.length()); // remove first letter
} while (word.length() > 0);
return EXIT_SUCCESS;
}
但是,我得到的实际输出是:
f?r? ? ? 字母:f字母:? 信:r
源文件以UTF8编码,控制台的编码也设置为UTF8。
这是Sehe提供的解决方案:
#include <iostream>
#include <string>
#include <boost/regex/pending/unicode_iterator.hpp>
using namespace std;
template <typename C>
std::string to_utf8(C const& in)
{
std::string result;
auto out = std::back_inserter(result);
auto utf8out = boost::utf8_output_iterator<decltype(out)>(out);
std::copy(begin(in), end(in), utf8out);
return result;
}
int main() {
wstring word = L"für";
bool isLastLetter;
do {
isLastLetter = ( word.length() == 1 );
auto currentLetter = to_utf8(word.substr(0, 1));
cout << "Letter: " << currentLetter << endl;
word = word.substr(1, word.length()); // remove first letter
} while (word.length() > 0);
return EXIT_SUCCESS;
}
输出:
Letter: f
Letter: ü
Letter: r
是的,您需要Boost,但似乎仍然需要外部库。
C ++不了解Unicode。 使用诸如ICU(UnicodeString类)或Qt(QString类)之类的外部库,它们都支持Unicode,包括UTF-8。
由于UTF-8具有可变长度,因此各种索引将以代码单位而非代码点进行索引。 由于它是可变长度的,因此不可能对UTF-8序列中的代码点进行随机访问。 如果要随机访问,则需要使用固定长度的编码,例如UTF-32。 为此,您可以在字符串上使用U前缀。
C ++语言标准没有显式编码的概念。 它仅包含“系统编码”的不透明概念,其wchar_t是“足够大”的类型。
要将不透明的系统编码转换为显式的外部编码,必须使用外部库。 选择的库是iconv()(从WCHAR_T到UTF-8),它是Posix的一部分,可在许多平台上使用,尽管可以保证Windows上的WideCharToMultibyte函数可以生成UTF8。
C ++ 11以std :: string s = u8“ Hello World:\\ U0010FFFF”;的形式添加了新的UTF8文字。 那些已经在UTF8中了,但是除了我所描述的方式之外,它们无法与不透明的wstring交互。
用C ++进行编码相当复杂。 这是我对此的理解。
每个实现都必须支持基本源字符集中的字符。 这些包括§2.2/ 1(C ++ 11中的§2.3/ 1)中列出的常见字符。 这些字符都应适合一个字符。 另外,实现还必须支持一种使用通用字符名称的方式来命名其他字符的方式,其外观类似于\\ uffff或\\ Uffffffff,并且可以用来引用Unicode字符。 它们的一个子集可用于标识符(在附录E中列出)。
一切都很好,但是从文件中的字符到源字符(在编译时使用)的映射是实现定义的。 这构成了所使用的编码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.