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

标签 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);
}

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

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

此后,标记数组完全为空。据我猜测,发生这种情况是因为该行

tokens = new string[length];

我认为标记数组作为局部变量的内存空间已分配,当 split 函数完成时,该内存空间将在 block 完成时释放。

当我尝试调试时,分割函数本身工作得很好,因为标记数组至少在分割函数 block 中充满了标记。我认为我的猜测是正确的,但是我该如何解决这个问题呢?有什么解决办法吗?我认为这不仅仅是 std::string 数组的问题,这是“按引用调用”的作业。

要求

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

提前感谢您的精彩回答!

最佳答案

正如 @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++ std::string 数组作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29464141/

相关文章:

c++ - 有没有办法创建一个公共(public)输出流对象以在控制台上打印并打印到 C++ 中的文件?

android - iOS和Android通用随机数生成器

c++ - 不使用 count() 将一个数组的每个元素的计数赋给另一个数组的每个元素

python - 从给定的字符串 S 中删除多少个字符才能使它成为一个排序的字符串

c++ - 我什么时候使用引用?

python - PyCharm:在 'xxx' 中找不到引用 'turtle.py'

c++ - 未使用依赖类型的“预期主表达式”错误

java - 如何将字符串排序到映射中并打印结果

c# - Unity3d:通过GetComponent错误从另一个脚本访问类

Java charAt() 字符串索引超出范围