【问题标题】:c++ std::string array as function parameterc++ std::string 数组作为函数参数
【发布时间】:2015-04-06 01:17:08
【问题描述】:

我对 C++ 有点陌生。我想为 c++ 中的 std::string 创建拆分函数,例如 String 类中的 java split 函数(我不想使用 boost 库)。所以我制作了自定义拆分功能,即..

using namespace std;

void ofApp::split(string ori, string tokens[], string deli){
    // calculate the number of tokens
    int length = 0;
    int curPos = 0;

    do{
        curPos = ori.find(deli, curPos) + 1;
        length++;
    }while(ori.find(deli, curPos) != string::npos);
    length++;

    // to save tokens, initialize tokens array
    tokens = new string[length];   // this is the line I'm suspicious about..

    int startPos = 0;
    int strLength = 0;
    int curIndex = 0;
    do{
        strLength = ori.find(deli, startPos) - startPos;
        tokens[curIndex++] = ori.substr(startPos, strLength);
        startPos = ori.find(deli, startPos) + 1;
    }while(ori.find(deli, startPos) != string::npos);
    tokens[curIndex] = ori.substr(startPos, ori.length() - startPos);
}

首先,我认为传递参数为 string tokens[] 是通过引用调用的方式,所以当函数完成时,tokens[] 数组将充满由熟食字符串分隔的标记。但是当我像这样调用这个函数时

string str = "abc,def,10.2,dadd,adsf";
string* tokens;
split(str, tokens, ",");

在此之后,tokens 数组完全为空。我猜,这是因为这条线

tokens = new string[length];

我认为令牌数组作为局部变量的内存空间已分配,当拆分功能完成时,该内存空间将在块完成时释放。

当我尝试调试时,拆分函数本身运行良好,因为令牌数组至少在拆分函数块中充满了令牌。我认为我的猜测是正确的,但我该如何解决这个问题?有什么解决办法吗?我认为这不仅仅是 std::string 数组的问题,这是“通过引用调用”的作业。

要求

  1. 将 std::string[] 类型传递给函数参数(返回 tokens[] 也可以。但我认为这会有同样的问题)
  2. 函数完成后,数组必须充满标记
  3. tokens数组长度必须在split函数中计算(如果用户必须计算tokens长度,这是一个愚蠢的函数)。因此,无法在 split 函数调用之前分配令牌数组的内存。

非常感谢您的精彩回答!

【问题讨论】:

  • 除非参数是引用(带 &),否则不会通过引用传递任何内容。
  • 我明白了.... 那我该怎么办?实际上,我尝试使用 & 但它给出了很多错误,我放弃了。与原始类型数组不同,字符串数组的单元格大小不像 4 字节那样固定。我认为这是某种问题。我想我真的是 C++ 的菜鸟。我用过很多种语言,如C#、Java、AS3、Lua、Python等,但我真的不会用好C++..它太复杂了
  • 我可能只返回一个std::vector<std::string> 而不是强制输出参数并且没有返回值。
  • 有可能吗?如果我返回 std::vector<:string>,我必须在 split 函数块中为 std::vector<:string> 变量分配内存,当我返回它时,这个变量不是免费的吗?因为这个变量内存空间是在本地块中分配的..???
  • 创建局部变量std::vector&lt;std::string&gt; tokens;并在其上使用push_backresize函数,并从函数中按值返回。它会起作用的。没有new 表示没有问题!在 C++ 中,new 不好。

标签: c++ string reference tokenize


【解决方案1】:

正如@chris 所建议的,类似下面的代码应该可以工作。

示例代码

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> split(const std::string& delimiter, const std::string& str)
{
    std::vector<std::string> result;

    std::size_t prevPos = 0;
    while (prevPos != std::string::npos)
    {
        std::size_t currPos = str.find(delimiter, prevPos);
        result.push_back(str.substr(prevPos, currPos - prevPos));

        prevPos = currPos;

        if (prevPos != std::string::npos)
        {
            // Skip the delimiter
            prevPos += delimiter.size();
        }
    }

    return result;
}

int main()
{
    std::string str("this,is,a,test");
    std::vector<std::string> splitResult = split(",", str);
    for (const auto &s : splitResult)
    {
        std::cout << "'" << s << "'\n";
    }

    std::cout << "\n";

    str = "this - is - a - test";
    splitResult = split(" - ", str);
    for (const auto &s : splitResult)
    {
        std::cout << "'" << s << "'\n";
    }

    return 0;
}

示例输出

'this'
'is'
'a'
'test'

'this'
'is'
'a'
'test'

【讨论】:

  • 非常感谢。 C++ 让我发疯……但是 CODING WORLD,当我越走越深,我认为最终 C++ 是必要的……
猜你喜欢
  • 2018-12-23
  • 2016-06-10
  • 2014-02-19
  • 1970-01-01
  • 2011-02-21
  • 2011-01-22
  • 2019-06-04
  • 1970-01-01
  • 2020-11-29
相关资源
最近更新 更多