【问题标题】:Convert a unicode String In C++ To Upper Case将 C++ 中的 unicode 字符串转换为大写
【发布时间】:2013-08-02 05:18:26
【问题描述】:

我们如何在 C 或 C++ 中将多语言字符串或 unicode 字符串转换为大写/小写。

【问题讨论】:

  • 检查此线程stackoverflow.com/questions/1614595/…。它可能会帮助你。
  • “Unicode”是什么意思? Unicode 标准定义了许多不同的编码——您使用的是哪一种? UTF-8? UTF-16? UTF-32?
  • 在这里提出问题之前先谷歌一下
  • 对于 unicode,如果使用全大写比较,请务必小心,因为许多实现无法正确检查哪些字符是大写或小写。

标签: c++ string unicode


【解决方案1】:

如果你的系统已经是 UTF-8,通过使用std::use_facet,你可以这样写:

#include <iostream>
#include <locale.h>

int main() {
    std::locale::global(std::locale(""));  // (*)
    std::wcout.imbue(std::locale());
    auto& f = std::use_facet<std::ctype<wchar_t>>(std::locale());

    std::wstring str = L"Zoë Saldaña played in La maldición del padre Cardona.";

    f.toupper(&str[0], &str[0] + str.size());
    std::wcout << str << std::endl;

    return 0;
}

你会得到 (http://ideone.com/AFHoHC):

ZOË SALDAÑA 在 LA MALDICIÓN DEL PADRE CARDONA 演出。

如果它不起作用,您将不得不将 (*) 更改为 std::locale::global(std::locale("en_US.UTF8")); 或您在平台上实际拥有的 UTF-8 语言环境。

【讨论】:

  • 这是如果您的 stdlib 支持语言环境,并且您的 UTF-8 语言环境名为“en_US.UTF8”。这是一个很好的 C++ 解决方案,但 C++ 解决方案本身就很不便携。
  • @rubenvb:是的,当然你必须检查 UTF-8 语言环境是否存在。 std::locale::global(std::locale("")) 实际上不会做这项工作吗?
  • @Kyle_the_hacker 如果我设置 std::locale::global(std::locale("en_US.UTF-8"));在 Apple LLVM 4.2 编译器上,但不在 LLVM GCC 4.2 编译器上。我认为 LLVM GCC 不支持“自动”。
  • @Pankaj:哇,那是一个旧的编译器!尝试将auto&amp; 替换为const std::ctype&lt;wchar_t&gt;&amp;
【解决方案2】:

我找到了该问题的 2 个解决方案_

1。 setlocale(LC_CTYPE, "en_US.UTF-8"); // 语言环境将是启用 UTF-8 的英语

std::wstring str = L"Zoë Saldaña played in La maldición del padre Cardona.ëèñ";

std::wcout << str << std::endl;

for (wstring::iterator it = str.begin(); it != str.end(); ++it)
    *it = towupper(*it);

std::wcout << "toUpper_onGCC_LLVM_1 :: "<< str << std::endl;

这适用于 LLVM GCC 4.2 编译器。

2。 std::locale::global(std::locale("en_US.UTF-8")); // 语言环境将是启用 UTF-8 的英语

std::wcout.imbue(std::locale());
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale());

std::wstring str = L"Chloëè";//"Zoë Saldaña played in La maldición del padre Cardona.";

f.toupper(&str[0], &str[0] + str.size());   

std::wcout << str << std::endl;

这适用于 Apple LLVM 4.2。

这两种情况我都在 Xocde 上运行。 但我正在寻找一种使用 g++ 编译器在 Eclipse 中运行此代码的方法。

【讨论】:

  • 您阅读其他答案了吗?你基本上复制/粘贴了@mewa 和我的答案......
【解决方案3】:

如果你要做好的话,难度很大。

这通常用于比较目的,但问题比这更普遍。

有一篇相当详细的论文来自 Matt Austern here 大约 2000 年的 C++ 报告 (PDF)

【讨论】:

  • 不区分大小写比较的大写是错误的方法。正确的方法是去除only的大小写差异(有一种称为“casefolding”的操作可用于此),然后进行比较。大写并不能消除only大小写差异。
  • 我什至不同意这种说法。您想消除与比较无关的所有差异。当然,Æ = æ,但这可能等于 AE、ae 和 AE。
  • 这不是答案
【解决方案4】:

如果您想要一个健全而成熟的解决方案,请查看IBM's ICU。这是一个例子:

#include <iostream>
#include <unicode/unistr.h>
#include <string>

int main(){
    icu::UnicodeString us("óóßChloë");
    us.toUpper(); //convert to uppercase in-place
    std::string s;
    us.toUTF8String(s);
    std::cout<<"Upper: "<<s<<"\n";

    us.toLower(); //convert to lowercase in-place
    s.clear();
    us.toUTF8String(s);
    std::cout<<"Lower: "<<s<<"\n";
    return 0;
}

输出:

Upper: ÓÓSSCHLOË
Lower: óósschloë

注意:在后面的步骤中,SS 不被视为德国的首都ß

【讨论】:

  • 看起来确实是一个不错的库。但是,它的时钟接近 30MB。我的整个应用程序是 21MB。
【解决方案5】:

您可以遍历 wstring 并使用 towupper / towlower

for (wstring::iterator it = a.begin(); it != a.end(); ++it)
        *it = towupper(*it);

【讨论】:

    【解决方案6】:

    设置locale first,示例:

    setlocale(LC_ALL, "German")); /*This won't work as per comments below */
    
    setlocale(LC_ALL, "English"));
    
    setlocale( LC_MONETARY, "French" );
    
    setlocale( LC_ALL, "" ); //default locale 
    

    然后使用

    std::use_facetstd::locale如下:-

    typedef std::string::value_type char_t;
    char_t upcase( char_t ch )
    {
     return std::use_facet< std::ctype< char_t > >( std::locale() ).toupper( ch );
    }
    
    std::string toupper( const std::string &src )
    {
     std::string result;
     std::transform( src.begin(), src.end(), std::back_inserter( result ), upcase );
     return result;
    }
    
    const std::string src  = "Hello World!";
    std::cout << toupper( src );
    

    【讨论】:

    • 有趣的是您提到了德语语言环境,然后继续使用一种不适用于正确的德语大写的方法,因为它使用一对一映射 (transform),但是大写 ß 会产生两个字符。
    • 实际上我想转换法语文本,所以我使用 setlocale( LC_MONETARY, "French" );但是当我将 chloë 转换为大写时,将 CHLOë 作为输出。
    • @Pankaj 请,请,请,请不要意外停止编程。你认为setlocale(LC_MONETARY, "French") 做了什么?你认为大写的“Chloë”有任何金钱问题吗?如果您的问题是查找文档,这里是 en.cppreference.com/w/cpp/locale/setlocale 和这里 en.cppreference.com/w/cpp/locale/LC_categories
    • @Pankaj 你到底想从“Chloë 那里得到什么?请别管她 ;)
    • @P0W Cholë 改成大写后应该像 CHOLË 一样。
    【解决方案7】:

    在 Windows 中,对于语言环境未知的混合语言应用程序,请考虑使用 CharUpperBuffWCharLowerBuffW。这些函数处理 toupper() 不处理的变音符号。

    【讨论】:

    • 使用特定于平台的函数来操作文本只有缺点——它将您的代码绑定到该平台并且对您没有任何好处。考虑到有很多优秀的文本操作库不是特定于平台的,这样做只会伤害自己。
    • 天真地认为在所有平台上运行所有应用程序是有益或有利可图的。
    • 认为您的程序永远不会在您现在正在开发的平台之外的任何其他平台上运行是天真的。当存在优越的非平台特定 API 时,使用低劣的 API 将自己绑定到平台是非常愚蠢的。
    【解决方案8】:

    对于 C,我将在当前线程中调整 C 语言环境后使用toupper

    setlocale(LC_CTYPE, "en_US.UTF8");
    

    对于 C++,我会使用 std::ctype&lt;char&gt;toupper 方法:

    std::locale loc;
    
    auto& f = std::use_facet<std::ctype<char>>(loc);
    
    char str[80] = "Hello World";
    
    f.toupper(str, str+strlen(str));
    

    【讨论】:

    • 我的代码是:- setlocale(LC_CTYPE, "en_US.UTF8"); std::locale 位置; auto& f = std::use_facet<:ctype>>(loc); char str[80] = "pièces"; f.toupper(str, str+strlen(str)); cout
    • @Pankaj 这是因为 en_US 语言环境没有大写形式的任何不在 a-z 中的内容。
    • @R.MartinhoFernandes 所以我必须为此做些什么,实际上我对 CPP 很陌生,我什至不知道 CPP 中的 hello world 程序。一些我如何管理它..
    • @Pankaj:使用适当的语言环境。例如,在土耳其语中,i 的大写字母是 İ(保留上面的点)。土耳其语言环境知道这一点,美国知道大写的 i 是不带点的 I。当然,两者都是正确的。
    • @Kyle_the_hacker 哦,我错过了 Pankaj 是如何使用 cout 打印东西的。好点子。
    【解决方案9】:

    基于Kyle_the_hacker's -----> answer 和我的临时演员。

    Ubuntu

    在终端 列出所有语言环境
    locale -a

    安装所有语言环境
    sudo apt-get install -y locales locales-all

    编译main.cpp
    $ g++ main.cpp

    运行编译好的程序
    $ ./a.out

    结果

    Zoë Saldaña played in La maldición del padre Cardona. ëèñ αω óóChloë
    Zoë Saldaña played in La maldición del padre Cardona. ëèñ αω óóChloë
    ZOË SALDAÑA PLAYED IN LA MALDICIÓN DEL PADRE CARDONA. ËÈÑ ΑΩ ÓÓCHLOË
    ZOË SALDAÑA PLAYED IN LA MALDICIÓN DEL PADRE CARDONA. ËÈÑ ΑΩ ÓÓCHLOË
    zoë saldaña played in la maldición del padre cardona. ëèñ αω óóchloë
    zoë saldaña played in la maldición del padre cardona. ëèñ αω óóchloë
    

    窗口

    在 cmd 中运行 VCVARS 开发者工具
    "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"

    编译main.cpp
    &gt; cl /EHa main.cpp /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /std:c++17 /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MTd

    Compilador de optimización de C/C++ de Microsoft (R) versión 19.27.29111 para x64
    (C) Microsoft Corporation. Todos los derechos reservados.
    
    main.cpp
    Microsoft (R) Incremental Linker Version 14.27.29111.0
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /out:main.exe
    main.obj
    kernel32.lib
    user32.lib
    gdi32.lib
    winspool.lib
    comdlg32.lib
    advapi32.lib
    shell32.lib
    ole32.lib
    oleaut32.lib
    uuid.lib
    odbc32.lib
    odbccp32.lib
    

    运行 main.exe
    &gt;main.exe

    结果

    Zoë Saldaña played in La maldición del padre Cardona. ëèñ αω óóChloë
    Zoë Saldaña played in La maldición del padre Cardona. ëèñ αω óóChloë
    ZOË SALDAÑA PLAYED IN LA MALDICIÓN DEL PADRE CARDONA. ËÈÑ ΑΩ ÓÓCHLOË
    ZOË SALDAÑA PLAYED IN LA MALDICIÓN DEL PADRE CARDONA. ËÈÑ ΑΩ ÓÓCHLOË
    zoë saldaña played in la maldición del padre cardona. ëèñ αω óóchloë
    zoë saldaña played in la maldición del padre cardona. ëèñ αω óóchloë
    

    代码 - main.cpp

    此代码仅在 Windows x64 和 Ubuntu Linux x64 上测试。

    /*
     * Filename: c:\Users\x\Cpp\main.cpp
     * Path: c:\Users\x\Cpp
     * Filename: /home/x/Cpp/main.cpp
     * Path: /home/x/Cpp
     * Created Date: Saturday, October 17th 2020, 10:43:31 pm
     * Author: Joma
     *
     * No Copyright 2020
     */
    
    
    #include <iostream>
    #include <set>
    #include <string>
    #include <locale>
    
    // WINDOWS
    #if (_WIN32)
    #include <Windows.h>
    #include <conio.h>
    #define WINDOWS_PLATFORM 1
    #define DLLCALL STDCALL
    #define DLLIMPORT _declspec(dllimport)
    #define DLLEXPORT _declspec(dllexport)
    #define DLLPRIVATE
    #define NOMINMAX
    
    //EMSCRIPTEN
    #elif defined(__EMSCRIPTEN__)
    #include <emscripten/emscripten.h>
    #include <emscripten/bind.h>
    #include <unistd.h>
    #include <termios.h>
    #define EMSCRIPTEN_PLATFORM 1
    #define DLLCALL
    #define DLLIMPORT
    #define DLLEXPORT __attribute__((visibility("default")))
    #define DLLPRIVATE __attribute__((visibility("hidden")))
    
    // LINUX - Ubuntu, Fedora, , Centos, Debian, RedHat
    #elif (__LINUX__ || __gnu_linux__ || __linux__ || __linux || linux)
    #define LINUX_PLATFORM 1
    #include <unistd.h>
    #include <termios.h>
    #define DLLCALL CDECL
    #define DLLIMPORT
    #define DLLEXPORT __attribute__((visibility("default")))
    #define DLLPRIVATE __attribute__((visibility("hidden")))
    #define CoTaskMemAlloc(p) malloc(p)
    #define CoTaskMemFree(p) free(p)
    
    //ANDROID
    #elif (__ANDROID__ || ANDROID)
    #define ANDROID_PLATFORM 1
    #define DLLCALL
    #define DLLIMPORT
    #define DLLEXPORT __attribute__((visibility("default")))
    #define DLLPRIVATE __attribute__((visibility("hidden")))
    
    //MACOS
    #elif defined(__APPLE__)
    #include <unistd.h>
    #include <termios.h>
    #define DLLCALL
    #define DLLIMPORT
    #define DLLEXPORT __attribute__((visibility("default")))
    #define DLLPRIVATE __attribute__((visibility("hidden")))
    #include "TargetConditionals.h"
    #if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
    #define IOS_SIMULATOR_PLATFORM 1
    #elif TARGET_OS_IPHONE
    #define IOS_PLATFORM 1
    #elif TARGET_OS_MAC
    #define MACOS_PLATFORM 1
    #else
    
    #endif
    
    #endif
    
    
    
    typedef std::string String;
    typedef std::wstring WString;
    
    #define EMPTY_STRING u8""s
    #define EMPTY_WSTRING L""s
    
    using namespace std::literals::string_literals;
    
    class Strings
    {
    public:
        static String WideStringToString(const WString& wstr)
        {
            if (wstr.empty())
            {
                return String();
            }
            size_t pos;
            size_t begin = 0;
            String ret;
    
    #if WINDOWS_PLATFORM
            int size;
            pos = wstr.find(static_cast<wchar_t>(0), begin);
            while (pos != WString::npos && begin < wstr.length())
            {
                WString segment = WString(&wstr[begin], pos - begin);
                size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), NULL, 0, NULL, NULL);
                String converted = String(size, 0);
                WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.size(), NULL, NULL);
                ret.append(converted);
                ret.append({ 0 });
                begin = pos + 1;
                pos = wstr.find(static_cast<wchar_t>(0), begin);
            }
            if (begin <= wstr.length())
            {
                WString segment = WString(&wstr[begin], wstr.length() - begin);
                size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), NULL, 0, NULL, NULL);
                String converted = String(size, 0);
                WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.size(), NULL, NULL);
                ret.append(converted);
            }
    #elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
            size_t size;
            pos = wstr.find(static_cast<wchar_t>(0), begin);
            while (pos != WString::npos && begin < wstr.length())
            {
                WString segment = WString(&wstr[begin], pos - begin);
                size = wcstombs(nullptr, segment.c_str(), 0);
                String converted = String(size, 0);
                wcstombs(&converted[0], segment.c_str(), converted.size());
                ret.append(converted);
                ret.append({ 0 });
                begin = pos + 1;
                pos = wstr.find(static_cast<wchar_t>(0), begin);
            }
            if (begin <= wstr.length())
            {
                WString segment = WString(&wstr[begin], wstr.length() - begin);
                size = wcstombs(nullptr, segment.c_str(), 0);
                String converted = String(size, 0);
                wcstombs(&converted[0], segment.c_str(), converted.size());
                ret.append(converted);
            }
    #else
            static_assert(false, "Unknown Platform");
    #endif
            return ret;
        }
    
        static WString StringToWideString(const String& str)
        {
            if (str.empty())
            {
                return WString();
            }
    
            size_t pos;
            size_t begin = 0;
            WString ret;
    #ifdef WINDOWS_PLATFORM
            int size = 0;
            pos = str.find(static_cast<char>(0), begin);
            while (pos != std::string::npos) {
                std::string segment = std::string(&str[begin], pos - begin);
                std::wstring converted = std::wstring(segment.size() + 1, 0);
                size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.length());
                converted.resize(size);
                ret.append(converted);
                ret.append({ 0 });
                begin = pos + 1;
                pos = str.find(static_cast<char>(0), begin);
            }
            if (begin < str.length()) {
                std::string segment = std::string(&str[begin], str.length() - begin);
                std::wstring converted = std::wstring(segment.size() + 1, 0);
                size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, segment.c_str(), segment.size(), &converted[0], converted.length());
                converted.resize(size);
                ret.append(converted);
            }
    
    #elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
            size_t size;
            pos = str.find(static_cast<char>(0), begin);
            while (pos != String::npos)
            {
                String segment = String(&str[begin], pos - begin);
                WString converted = WString(segment.size(), 0);
                size = mbstowcs(&converted[0], &segment[0], converted.size());
                converted.resize(size);
                ret.append(converted);
                ret.append({ 0 });
                begin = pos + 1;
                pos = str.find(static_cast<char>(0), begin);
            }
            if (begin < str.length())
            {
                String segment = String(&str[begin], str.length() - begin);
                WString converted = WString(segment.size(), 0);
                size = mbstowcs(&converted[0], &segment[0], converted.size());
                converted.resize(size);
                ret.append(converted);
            }
    #else
            static_assert(false, "Unknown Platform");
    #endif
            return ret;
        }
    
    
        static WString ToUpper(const WString& data)
        {
            WString result = data;
            auto& f = std::use_facet<std::ctype<wchar_t>>(std::locale());
    
            f.toupper(&result[0], &result[0] + result.size());
            return result;
        }
    
        static String  ToUpper(const String& data)
        {
            return WideStringToString(ToUpper(StringToWideString(data)));
        }
    
        static WString ToLower(const WString& data)
        {
            WString result = data;
            auto& f = std::use_facet<std::ctype<wchar_t>>(std::locale());
            f.tolower(&result[0], &result[0] + result.size());
            return result;
        }
    
        static String ToLower(const String& data)
        {
            return WideStringToString(ToLower(StringToWideString(data)));
        }
    
    };
    
    enum class ConsoleTextStyle
    {
        DEFAULT = 0,
        BOLD = 1,
        FAINT = 2,
        ITALIC = 3,
        UNDERLINE = 4,
        SLOW_BLINK = 5,
        RAPID_BLINK = 6,
        REVERSE = 7,
    };
    
    enum class ConsoleForeground
    {
        DEFAULT = 39,
        BLACK = 30,
        DARK_RED = 31,
        DARK_GREEN = 32,
        DARK_YELLOW = 33,
        DARK_BLUE = 34,
        DARK_MAGENTA = 35,
        DARK_CYAN = 36,
        GRAY = 37,
        DARK_GRAY = 90,
        RED = 91,
        GREEN = 92,
        YELLOW = 93,
        BLUE = 94,
        MAGENTA = 95,
        CYAN = 96,
        WHITE = 97
    };
    
    enum class ConsoleBackground
    {
        DEFAULT = 49,
        BLACK = 40,
        DARK_RED = 41,
        DARK_GREEN = 42,
        DARK_YELLOW = 43,
        DARK_BLUE = 44,
        DARK_MAGENTA = 45,
        DARK_CYAN = 46,
        GRAY = 47,
        DARK_GRAY = 100,
        RED = 101,
        GREEN = 102,
        YELLOW = 103,
        BLUE = 104,
        MAGENTA = 105,
        CYAN = 106,
        WHITE = 107
    };
    
    class Console
    {
    private:
        static void EnableVirtualTermimalProcessing()
        {
    #if defined WINDOWS_PLATFORM
            HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            DWORD dwMode = 0;
            GetConsoleMode(hOut, &dwMode);
            if (!(dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING))
            {
                dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
                SetConsoleMode(hOut, dwMode);
            }
    #endif
        }
    
        static void ResetTerminalFormat()
        {
            std::cout << u8"\033[0m";
        }
    
        static void SetVirtualTerminalFormat(ConsoleForeground foreground, ConsoleBackground background, std::set<ConsoleTextStyle> styles)
        {
            String format = u8"\033[";
            format.append(std::to_string(static_cast<int>(foreground)));
            format.append(u8";");
            format.append(std::to_string(static_cast<int>(background)));
            if (styles.size() > 0)
            {
                for (auto it = styles.begin(); it != styles.end(); ++it)
                {
                    format.append(u8";");
                    format.append(std::to_string(static_cast<int>(*it)));
                }
            }
            format.append(u8"m");
            std::cout << format;
        }
    public:
        static void Clear()
        {
    
    #ifdef WINDOWS_PLATFORM
            std::system(u8"cls");
    #elif LINUX_PLATFORM || defined MACOS_PLATFORM
            std::system(u8"clear");
    #elif EMSCRIPTEN_PLATFORM
            emscripten::val::global()["console"].call<void>(u8"clear");
    #else
            static_assert(false, "Unknown Platform");
    #endif
        }
    
        static void Write(const String& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
        {
    #ifndef EMSCRIPTEN_PLATFORM
            EnableVirtualTermimalProcessing();
            SetVirtualTerminalFormat(foreground, background, styles);
    #endif
            String str = s;
    #ifdef WINDOWS_PLATFORM
            WString unicode = Strings::StringToWideString(str);
            WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), static_cast<DWORD>(unicode.length()), nullptr, nullptr);
    #elif defined LINUX_PLATFORM || defined MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
            std::cout << str;
    #else
            static_assert(false, "Unknown Platform");
    #endif
    
    #ifndef EMSCRIPTEN_PLATFORM
            ResetTerminalFormat();
    #endif
        }
    
        static void WriteLine(const String& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
        {
            Write(s, foreground, background, styles);
            std::cout << std::endl;
        }
    
        static void Write(const WString& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
        {
    #ifndef EMSCRIPTEN_PLATFORM
            EnableVirtualTermimalProcessing();
            SetVirtualTerminalFormat(foreground, background, styles);
    #endif
            WString str = s;
    
    #ifdef WINDOWS_PLATFORM
            WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), str.c_str(), static_cast<DWORD>(str.length()), nullptr, nullptr);
    #elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
            std::cout << Strings::WideStringToString(str);
    #else
            static_assert(false, "Unknown Platform");
    #endif
    
    #ifndef EMSCRIPTEN_PLATFORM
            ResetTerminalFormat();
    #endif
        }
    
        static void WriteLine(const WString& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
        {
            Write(s, foreground, background, styles);
            std::cout << std::endl;
        }
    
        static void WriteLine()
        {
            std::cout << std::endl;
        }
    
        static void Pause()
        {
            char c;
            do
            {
                c = getchar();
                std::cout << "Press Key " << std::endl;
            } while (c != 64);
            std::cout << "KeyPressed" << std::endl;
        }
    
        static int PauseAny(bool printWhenPressed = false, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
        {
            int ch;
    #ifdef WINDOWS_PLATFORM
            ch = _getch();
    #elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
            struct termios oldt, newt;
            tcgetattr(STDIN_FILENO, &oldt);
            newt = oldt;
            newt.c_lflag &= ~(ICANON | ECHO);
            tcsetattr(STDIN_FILENO, TCSANOW, &newt);
            ch = getchar();
            tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    #else
            static_assert(false, "Unknown Platform");
    #endif
            if (printWhenPressed)
            {
                Console::Write(String(1, ch), foreground, background, styles);
            }
            return ch;
        }
    };
    
    
    
    int main()
    {
        std::locale::global(std::locale(u8"en_US.UTF-8"));
        String dataStr = u8"Zoë Saldaña played in La maldición del padre Cardona. ëèñ αω óóChloë";
        WString dataWStr = L"Zoë Saldaña played in La maldición del padre Cardona. ëèñ αω óóChloë";
        std::string locale = u8"";
        //std::string locale = u8"de_DE.UTF-8";
        //std::string locale = u8"en_US.UTF-8";
        Console::WriteLine(dataStr);
        Console::WriteLine(dataWStr);
        dataStr = Strings::ToUpper(dataStr);
        dataWStr = Strings::ToUpper(dataWStr);
        Console::WriteLine(dataStr);
        Console::WriteLine(dataWStr);
        dataStr = Strings::ToLower(dataStr);
        dataWStr = Strings::ToLower(dataWStr);
        Console::WriteLine(dataStr);
        Console::WriteLine(dataWStr);
        
        
        Console::WriteLine(u8"Press any key to exit"s, ConsoleForeground::DARK_GRAY);
        Console::PauseAny();
    
        return 0;
    }
    
    

    【讨论】:

      猜你喜欢
      • 2021-10-05
      • 2017-01-26
      • 2010-10-18
      • 1970-01-01
      • 2012-01-08
      • 2020-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多