【问题标题】:C++: Join an array of WCHAR[]s?C++:加入一个 WCHAR[] 数组?
【发布时间】:2010-06-04 23:35:04
【问题描述】:

我有一个 WCHAR[] 数组。我怎样才能加入他们?

我知道数组长度。

[L"foo", L"bar"] => "foo, bar"

【问题讨论】:

    标签: c++ string unicode


    【解决方案1】:

    遍历这些字符串并将它们添加到std::wstring

    std::wstring all;
    
    wchar_t *data[] = { L"foo", ... };
    size_t data_count = sizeof(data) / sizeof(*data);
    
    for (size_t n = 0; n < data_count; ++n)
    {
        if (n != 0)
            all += L", ";
        all += data[n];
    }
    

    【讨论】:

    • +1,因为它是我回答的基础。虽然我会用我所拥有的替换循环处理。
    • 您应该将int n 更改为无符号类型(最好是size_t)。否则编译器会抱怨。
    • @BillyONeal - 感谢您提出int / size_t 问题。
    【解决方案2】:

    你的系统有wsprintf()吗?示例:

    wchar_t *a = { L"foo", L"bar" };
    wchar_t joined[1000];
    
    wsprintf(joined, "%S, %S", a[0], a[1])
    

    【讨论】:

      【解决方案3】:

      这对于模板函数来说似乎是一项不错的工作。我使用这个函数来连接字符串,但它需要任何支持前向迭代器的容器:

      template<typename oT, typename sepT, typename rT = oT> rT joinContainer(const oT & o, const sepT & sep) {
          rT out;
          auto it = o.begin();
          while(it != o.end()) {
              out += *it;
              if(++it != o.end()) out += sep;
          }
          return out;
      }
      

      你可以这样称呼它:

      vector<wstring> input = { L"foo", L"bar", L"baz" };
      wstring out = joinContainer<vector<wstring>, wstring, wstring>(input, L", ");;
      wcout << out << endl;
      

      输出如下所示:

      foo, bar, baz
      

      注意:如果你没有使用 C++11,你可以像这样声明迭代器而不是使用auto

      typename oT::const_iterator it = o.begin();
      

      【讨论】:

        【解决方案4】:

        R Samuel Klatchko 解决方案的略微改进版本。

        wchar_t *data[] = { L"foo", ... };
        size_t data_count = sizeof(data) / sizeof(*data);
        
        wchar_t result[STUFF];
        
        wcscpy(result, data[0]);
        for (std::size_t n = 1; n < data_count; ++n)
        {
            wcscat(result, L", ");
            wcscat(result, data[n]);
        }
        

        改进之处在于循环中没有if分支依赖。我已转换为 C 标准库的 wcsXXXX 函数,但如果可用,我会使用 std::wstring

        编辑:

        假设

        我知道数组长度。

        意思是“我知道我想加入的字符串的数量”,那么你不能使用我上面发布的内容,这需要你在编译时知道最终的目标字符串长度。

        如果您在编译时不知道,请使用其他方法(并且包含我所说的循环改进):

        wchar_t *data[] = { L"foo", ... };
        size_t data_count = sizeof(data) / sizeof(*data);
        
        std::wstring result(data[0]); //Assumes you're joining at least one string.
        for (std::size_t n = 1; n < data_count; ++n)
            result.append(L", ").append(data[n]);
        

        【讨论】:

        • 我肯定会使用 std::wstring,除非你知道 STUFF 有多大。您还应该添加一个空终止符。
        • @zdan:OP 明确指定他知道长度。 wcscpy 和 wcscat 添加适当的 NULL 终止符——不需要。
        • -1 用于引发缓冲区溢出并使用 Shlemiel 画家算法 (joelonsoftware.com/articles/fog0000000319.html)。
        • @dan04:我同意最好使用 std::wstring。我将其发布为一个示例,说明如何使用 C 标准库完成相同的事情。只要字符串不是很大,无论如何都无关紧要。 (画家 Shlemiel 的算法是 C 字符串处理系统糟糕的最大原因!)。至于缓冲区溢出,如果 OP 事先知道长度,它就不会缓冲区溢出,正如他所指出的那样。
        • @Billy:我将数组长度解释为输入数组元素的数量,而不是生成的输出缓冲区大小。关于 wcscat 的观点。
        猜你喜欢
        • 2013-02-02
        • 1970-01-01
        • 1970-01-01
        • 2010-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-01
        • 1970-01-01
        相关资源
        最近更新 更多