【问题标题】:How to assign a std::string to std::basic_string<unsigned short int, TRAITS_CLASS>(Unicode2String) on Linux如何在 Linux 上将 std::string 分配给 std::basic_string<unsigned short int, TRAITS_CLASS>(Unicode2String)
【发布时间】:2022-01-27 12:13:43
【问题描述】:

我正在使用 Linux 系统,我认为标准 Linux std::string 支持 Unicode 和 ASCII 字符。所以,我想在我的代码中使用std::string,但我从应用程序接收std::basic_string&lt;unsigned short int, TRAIT_CLASS&gt; 格式的字符串(同时支持Windows 和Linux)。 TRAITS_CLASS 如下:

class TRAITS_CLASS
{
    public:
        typedef unsigned short char_type;
        typedef unsigned short int_type;
        typedef size_t pos_type;
        typedef size_t off_type;
        typedef int state_type;

        static inline void assign(unsigned short &dest, const unsigned short &src)
        {
            dest = src;
        }

        static inline bool eq(const unsigned short &left, const unsigned short &right)
        {
            return left == right;
        }

        static inline bool lt(const unsigned short &left, const unsigned short &right)
        {
            return left < right;
        }

        static int compare(const unsigned short *p1, const unsigned short *p2, size_t count)
        {
            for (; 0 < count; --count, ++p1, ++p2)
            {
                if (!eq(*p1, *p2))
                {
                    return lt(*p1, *p2) ? -1 : 1;
                }
            }
            return 0;
        }

        static size_t length(const unsigned short *p)
        {
            size_t count = 0;
            while (*p++)
            {
                ++count;
            }
            return count;
        }

        static unsigned short* copy(unsigned short *p1, const unsigned short *p2, size_t count)
        {
            unsigned short *res = p1;
            for (; 0 < count; --count, ++p1, ++p2)
            {
                assign(*p1, *p2);
            }
            return res;
        }

        static const unsigned short* find(const unsigned short *p, size_t count,
                const unsigned short &value)
        {
            for (; 0 < count; --count, ++p)
            {
                if (eq(*p, value))
                {
                    return p;
                }
            }
            return 0;
        }

        static unsigned short* move(unsigned short *dest, const unsigned short *src, size_t count)
        {
            unsigned short *res = dest;
            if ((src < dest) && (dest < src + count))
            {
                for (dest += count, src += count; 0 < count; --count)
                {
                    assign(*--dest, *--src);
                }
            }
            else
            {
                for (; 0 < count; --count, ++dest, ++src)
                {
                    assign(*dest, *src);
                }
            }
            return res;
        }

        static unsigned short* assign(unsigned short *dest, size_t count, unsigned short value)
        {
            unsigned short *res = dest;
            for (; 0 < count; --count, ++dest)
            {
                assign(*dest, value);
            }
            return res;
        }

        static inline unsigned short to_char_type(const int_type &arg)
        {
            return static_cast<unsigned short>(arg);
        }

        static inline int_type to_int_type(const unsigned short &value)
        {
            return static_cast<int_type>(value);
        }

        static inline bool eq_int_type(const int_type &left, const int_type &right)
        {
            return left == right;
        }

        static inline int_type eof()
        {
            return static_cast<int_type>(EOF);
        }

        static inline int_type not_eof(const int_type &value)
        {
            return value != eof() ? value : 1;
        }
};

如何将普通的std::string 分配给上述std::basic_string 模板?喜欢:

basic_string<unsigned short int, TRAIT_ClASS> temp = u"string";

如果无法赋值,如何使用上面的basic_string模板?

【问题讨论】:

    标签: c++ linux stdstring char-traits


    【解决方案1】:

    我认为标准的 Linux std::string 支持 Unicode 和 ASCII 字符

    std::string(又名std::basic_string&lt;char&gt;)没有Unicode 或ASCII 的概念,它只知道char 元素,仅此而已。您可能会对 Linux 应用程序通常使用 UTF-8 字符串这一事实感到困惑,而 UTF-8 可以存储在 std::string 中(或者最好存储在 C++20 中的 std::u8string aka std:::basic_string&lt;char8_t&gt; 中)。但是,将此类责任分配给 std::string 的任何用法是您的代码的工作。

    如何将普通的std::string 分配给上述std::basic_string 模板?

    您不能直接std::string 分配给/来自另一个std::basic_string&lt;CharT&gt;,其中CharT 是与char 不同的字符类型。

    假设数据兼容,您将不得不使用类型转换来解决这个问题 - 在您的示例中并非如此! char 的大小为 1 个字节,但 unsigned short int 的大小为 2 个字节。因此,您的其他应用程序的 basic_strings 很可能使用 UCS-2/UTF-16,您无法将其存储在 std::string 中(好吧,无论如何,这不是您想要的方式),但您可以 在 Windows 上存储在std::u16string(又名std::basic_string&lt;char16_t&gt;)或std::wstring(又名std::basic_string&lt;wchar_t&gt;)中,例如:

    std::basic_string<unsigned short int, TRAITS_CLASS> temp =
        reinterpret_cast<const unsigned short int*>(u"string");
    
    // or:
    std::basic_string<unsigned short int, TRAITS_CLASS> temp(
        reinterpret_cast<const unsigned short int*>(u"string"),
        6);
    
    std::u16string str = u"string";
    
    std::basic_string<unsigned short int, TRAITS_CLASS> temp =
        reinterpret_cast<const unsigned short int*>(str.c_str());
    
    // or:
    std::basic_string<unsigned short int, TRAITS_CLASS> temp(
        reinterpret_cast<const unsigned short int*>(str.c_str()),
        str.size());
    
    std::basic_string<unsigned short int, TRAITS_CLASS> temp = ...;
    
    std::u16string str =
        reinterpret_cast<const char16_t*>(temp.c_str());
    
    // or:
    std::u16string str(
        reinterpret_cast<const char16_t*>(temp.c_str()),
        temp.size());
    

    如果您绝对需要在代码中使用 std::string,那么您必须在 UTF-8(或您想要的任何其他 char 兼容字符集)和其他应用程序的字符集之间转换 16 位格式(假设为 UCS-2/UTF-16),例如 std::wstring_convert 或第三方 Unicode 库,如 libiconv、ICU 等。

    【讨论】:

      猜你喜欢
      • 2017-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 2023-03-21
      • 2015-04-28
      • 2013-11-18
      • 2018-03-11
      相关资源
      最近更新 更多