none
char型をバイト範囲で出力させたい。 RRS feed

  • 質問

  • 下のコードで、autoを使用したループでは、「b」が、4バイト値で出力されます。
    ループの部分を共通関数として実装したいので、autoを使用したいのですが、
    どのような方法で実装できるでしょうか。

    int main()
    {
        std::string b = "あ";
        std::wstring c = L"あ";
        std::u16string d = u"あ";
        std::u32string e = U"あ";
    
        for (auto ch : b) {
            std::cout << std::hex << +ch << std::endl;
        }
    
        for (unsigned char ch : b) {
            std::cout << std::hex << +ch << std::endl;
        }
    
    }
    ffffff82
    ffffffa0
    82
    a0

    共通関数と実装したときのイメージ

    auto f = [](auto s) {
    
        for (auto ch : s) {
            std::cout << std::hex << +ch << std::endl;
        }
    };
    
    
    
    int main()
    {
    
        std::string b = "あ";
        std::wstring c = L"あ";
        std::u16string d = u"あ";
        std::u32string e = U"あ";
    
    
    
    
        f(b);
        f(c);
        f(d);
        f(e);
    
    }


    2021年12月6日 4:23

回答

  • バイト範囲というのがどういう意味かいまいちわからないのですが

    #include <iostream>
    
    template<typename T>
    inline auto toUnsign(T ch)
    {
        return static_cast<std::make_unsigned<T>::type>(ch);
    }
    
    template<typename T>
    void f(T source)
    {
        for (auto ch : source)
        {
            std::cout << std::hex << (0 + ch) << std::endl;
        }
    
        for (auto ch : source)
        {
            auto uch = toUnsign(ch);
            std::cout << std::hex << (0 + uch) << std::endl;
        }
    }
    
    int main()
    {
        std::string b = "あ";
        std::wstring c = L"あ";
        std::u16string d = u"あ";
        std::u32string e = U"あ";
    
        f(b);
        f(c);
        f(d);
        f(e);
    }
    


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2021年12月6日 11:11
    • 回答としてマーク Brillia 2021年12月7日 1:42
    2021年12月6日 9:47
  • バイト範囲は分かりませんね…。各stringのバイト表現を確認したいということでしょうか? 

    Visual Studio 2022で /std:c++latest で次のように書けます。C++の最新機能をふんだんに使っています。

    #include <format>
    #include <iostream>
    #include <span>
    #include <string>
    #include <string_view>
    #include <utility> using namespace std::literals; static void write(const char* prefix, auto const& string) { std::cout << prefix << "\t= "sv; for (auto ch : std::as_bytes(std::span{ string })) std::cout << std::format("{:02X}"sv, std::to_underlying(ch)); std::cout << std::endl; } #define WRITE(STR) write(#STR, STR) int main() { WRITE("あ"s); WRITE(L"あ"s); WRITE(u"あ"s); WRITE(U"あ"s); }

    これで得られるのは

    "あ"s   = 82A0
    L"あ"s  = 4230
    u"あ"s  = 4230
    U"あ"s  = 42300000


    • 編集済み 佐祐理 2021年12月6日 11:28
    • 回答としてマーク Brillia 2021年12月7日 1:42
    2021年12月6日 11:25

すべての返信

  • バイト範囲というのがどういう意味かいまいちわからないのですが

    #include <iostream>
    
    template<typename T>
    inline auto toUnsign(T ch)
    {
        return static_cast<std::make_unsigned<T>::type>(ch);
    }
    
    template<typename T>
    void f(T source)
    {
        for (auto ch : source)
        {
            std::cout << std::hex << (0 + ch) << std::endl;
        }
    
        for (auto ch : source)
        {
            auto uch = toUnsign(ch);
            std::cout << std::hex << (0 + uch) << std::endl;
        }
    }
    
    int main()
    {
        std::string b = "あ";
        std::wstring c = L"あ";
        std::u16string d = u"あ";
        std::u32string e = U"あ";
    
        f(b);
        f(c);
        f(d);
        f(e);
    }
    


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2021年12月6日 11:11
    • 回答としてマーク Brillia 2021年12月7日 1:42
    2021年12月6日 9:47
  • バイト範囲は分かりませんね…。各stringのバイト表現を確認したいということでしょうか? 

    Visual Studio 2022で /std:c++latest で次のように書けます。C++の最新機能をふんだんに使っています。

    #include <format>
    #include <iostream>
    #include <span>
    #include <string>
    #include <string_view>
    #include <utility> using namespace std::literals; static void write(const char* prefix, auto const& string) { std::cout << prefix << "\t= "sv; for (auto ch : std::as_bytes(std::span{ string })) std::cout << std::format("{:02X}"sv, std::to_underlying(ch)); std::cout << std::endl; } #define WRITE(STR) write(#STR, STR) int main() { WRITE("あ"s); WRITE(L"あ"s); WRITE(u"あ"s); WRITE(U"あ"s); }

    これで得られるのは

    "あ"s   = 82A0
    L"あ"s  = 4230
    u"あ"s  = 4230
    U"あ"s  = 42300000


    • 編集済み 佐祐理 2021年12月6日 11:28
    • 回答としてマーク Brillia 2021年12月7日 1:42
    2021年12月6日 11:25
  • バイト範囲=>1バイト範囲

    ffffff82
    ffffffa0

    82
    a0

    にしたかったのです。

    2021年12月7日 1:56