c ++ std :: string数组作为函数参数

时间:2015-04-06 01:17:09

标签: c++ string reference tokenize

我是C ++的新手。我想在c ++中为std :: string创建split函数,比如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);
}

首先,我认为传递参数为字符串tokens [] 是通过引用调用的方式,因此当函数完成时,tokens []数组将充满由deli字符串分隔的标记。但是当我把这个函数称为

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

之后,令牌数组完全为空。根据我的猜测,这是因为行

tokens = new string[length];

我认为将令牌数组的内存空间作为局部变量进行分配,当分割函数完成时,当块完成时,该内存空间将是空闲的。

当我尝试调试时,split函数本身工作得很好,因为tokens数组至少在split功能块中充满了令牌。我想我的猜测是正确的,但我怎样才能解决这个问题呢?有解决方案吗我认为这不仅仅是std :: string数组的问题,这是"通过引用调用"的作业。

要求

  1. 将std :: string []类型传递给函数参数(返回tokens []也可以。但我认为这会有同样的问题)
  2. 当功能完成时,数组必须满是令牌
  3. 标记数组长度必须在split函数中计算(如果用户必须计算标记长度,则它是愚蠢的函数)。因此,在分割函数调用之前,不能分配令牌数组的内存。
  4. 谢谢你的高级答案!

1 个答案:

答案 0 :(得分:2)

正如@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'