C++如何获取wstring的第一个字母
C++ How to get first letter of wstring
这听起来是一个简单的问题,但C++让它变得困难(至少对我来说):我有一个wstring,我想把第一个字母作为wchar_t对象,然后从字符串中删除第一个字母。
此处不适用于非ASCII字符:
wchar_t currentLetter = word.at(0);
因为它为德语元音变音符等字符返回两个字符(在循环中)。
这里也不起作用:
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 *'
还有其他想法吗?
干杯,
Martin
----更新-----以下是一些应该说明问题的可执行代码。该程序将循环所有字母并逐一输出:
#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,但看起来你无论如何都需要一个外部库。
1
C++对Unicode一无所知。使用外部库,如ICU(UnicodeString类)或Qt(QString类)都支持Unicode,包括UTF-8。
2
由于UTF-8具有可变长度,所以所有类型的索引都可以以代码单位而非代码点进行索引。这是不可能的对UTF-8序列中的代码点进行随机访问,因为可变长度的性质。如果你想要随机访问,你需要使用固定长度编码,如UTF-32。为此,可以使用U前缀在字符串上。
3
C++语言标准没有显式编码的概念。它只是包含"系统编码"的不透明概念,wchar_t是"足够大"的类型。
从不透明系统编码转换为显式外部编码编码时,必须使用外部库。选择的图书馆将是iconv()(从WCHAR_T到UTF-8),它是Posix和可在许多平台上使用,尽管在Windows上WideCharToMultibyte函数保证产生UTF8。
C++11以std::string s=u8"Hello"的形式添加了新的UTF8文字世界:\U0010FFFF";。这些已经在UTF8中,但不能与不透明wstring的接口,而不是通过描述。
4(关于源文件,但仍排序相关)
用C++进行编码有点复杂。以下是我的理解
每个实现都必须支持来自基本源的字符字符集。其中包括§2.2/1中列出的常见字符(C++11中的§2.3/1)。这些字符都应该放在一个字符中。在里面附加实现必须支持命名其他使用一种称为通用字符名的方式的字符\uffff或\Uffffff,可以用来指代unicode字符。A.它们的子集可用于标识符(见附件E)。
这一切都很好,但从文件中的字符到源字符(在编译时使用)是实现定义的。这构成了所使用的编码。
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- 如何仅读取文本文件中的第一个值
- 在C++中,如何在第一个"system()"结束后执行第二个"system()"?
- 查找不在标准中的第一个值::设置<int>最小-最大值
- C++:忽略第一个 cin.ignore 之后的输入
- 在C++中打印多个矢量的第一个值
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- C++第一个cout将不会打印
- 我们可以在第一个else-if条件结束后使用另一个else-if条件吗
- OpenGL:第二个VBO破坏了第一个VBO
- 为什么第一个Dynamic_cast没有投射到基类?
- OpenGL 2D游戏只绘制第二个精灵纹理而不是第一个
- C++ 为什么程序只读取第一个值
- 在我的第一个C++程序中需要一些帮助(简单)
- 为什么我的代码在第一个 if 语句处中断?
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 无法使我的第一个Windows OpenGL窗口抬起并运行
- 将参数初始化为构造函数,而不是第一个
- 无法在硬件模式下创建 SGX 安全区 - "invalid launch token"即使文档将无效的启动令牌指定为第一个