[英]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.