簡體   English   中英

對 UTF-8 字符串使用 boost::format %s 說明符

[英]Using boost::format %s specifier with UTF-8 strings

我們正在向具有大型代碼庫的現有應用程序添加對 UTF8 的支持。 此應用程序使用boost::format() ,並且非 ASCII 字符的輸出未正確對齊。 具體來說,當使用%{width}.{length} s 說明符時, boost::format()計算字符數,這不會對 utf8 字符串“做正確的事情”。 我認為應該可以根據...更改字符串長度代碼(可能是string::size() )以使用utf8len()或類似的東西?

在這種情況下,更改現有代碼庫以使用 UCS2(或 UCS4,或 UTF-16 等)是不切實際的,但如果需要,可以修改boost::format() 我希望其他人遇到過這種需求,並且可以為我指出可能的解決方案。

注意:我發現了一些關於使用 utf8 語言環境的網頁,但其中大部分似乎更適用於在流中轉換為 utf8 和 UCS4。

這對你來說可能為時已晚,但也許它會幫助其他人。 Boost::format 接受 std::locale 作為可選模板參數。 (參見http://www.boost.org/doc/libs/1_55_0/libs/format/doc/format.html )。 如果您將 unicod 感知區域設置傳遞給它,例如 boost::locale("en_US.UTF-8"),您應該獲得所需的行為。

除了每次都向 boost::format 構造函數傳遞語言環境之外,您還可以設置應用程序的默認語言環境,這可能有助於避免其他問題。 如果您采用這條路線,我會建議在 std::locale 上使用 boost::locale,因為 boost::locale 不會修改您的數字格式,除非您明確要求( 此處為文檔)。

通常,這是使 C++ 中的應用程序與 Unicode 很好地協同工作的一種 goto 方法。 如果功能可以使用語言環境(std::regex、std::sort、boost::format),給它一個 unicode 感知語言環境,你應該是安全的(如果你不是,請告訴我,我想知道)。

如果您正在制作一個小型、輕量級的應用程序並且只關心 80% 的情況,您可能不想為包含 ICU(Unicode 的國際組件)付出代價,它是提供 unide 支持時的默認引擎提升區域設置。 在這種情況下,使用您的操作系統或 Posix unicode 支持構建 Boos,您的應用程序將保持小而輕,但您不會有很多 unicode 支持,例如多個排序規則級別。

對於您所描述的問題,Posix 支持可能就足夠了。

即使使用基於 UTF-8 的語言環境,AFAIK Boost Format 也會以代碼單元測量所有內容。

如果您可以切換到另一個庫,那么請考慮 C++20 std::format{fmt} 格式化庫,它們以顯示寬度單位(類似於wcswidth )計算寬度,因此對齊是正確的。 例如

fmt::print("┌{0:─^{2}}┐\n"
           "│{1: ^{2}}│\n"
           "└{0:─^{2}}┘\n", "", "Hello, world!", 20);

印刷:

┌────────────────────┐
│   Hello, world!    │
└────────────────────┘

免責聲明:我是 {fmt} 和 C++20 std::format 的作者

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM