调试我重新实现strtok和split

时间:2016-10-31 21:53:22

标签: c++

我应该编写的代码采用一串逗号分隔的值,不带空格(例如my,name,is,jack)。首先,我们必须编写一个函数

string nextstring(string str, int start_index)

从初始字符串返回单个“值”,具体取决于起始索引。问题的第二部分是写一个函数

int split(string str, string a[], int max_size)

将识别初始字符串中的所有值并将它们放入字符串数组中,然后返回存储在数组中的值的总数;即如果你最初输入my,name,is,它将返回3.

我的函数永远不会返回正确的值,它返回的内容会根据单词的长度而变化。

#include <iostream>
#include <string>

using namespace std;

string nextstring(string str, int start_index);
int split(string str, string a[], int max_size);

int main()
{
    string str;
    int cnt;

    string a[100];

    cout<< "what is your string" << endl;
    getline(cin, str);
    cnt= split(str, a, 100);
    cout << "There are " << cnt << " values in this string" << endl;

    for(int i=0; i<cnt; i++)
    {
        cout << a[i] << endl;
    }

    return 0;

}

string nextstring(string str, int start_index)
{
    string ans;

    if(str[start_index] == ',' || str[start_index] == '\0')
    {
        ans=" ";
    }
    else{
        ans=str[start_index]+nextstring(str, start_index+1);
    }

    return ans;

}

int split(string str, string a[], int max_size)
{
    int j=0;
    int ans=0;
    double k=0;
    while(j<max_size)
    {
        a[j]= nextstring(str,k);
        string check=a[j];

        if(isalpha(check[0])!= 0)
        {
          ans++;
        }
        k=k+a[j].length();
        j++;
     }
    return ans;
}

2 个答案:

答案 0 :(得分:0)

您的问题似乎是while(j<max_size){...}导致j增加到max_size。行a[j]= nextstring(str,k);在某些点读取字符串之外的值非常糟糕!

while(j<max_size){...}替换while(j<max_size && k<str.length()){...}似乎足以让您的代码有效!

除此之外:

  1. k没有理由成为双倍!它应该是int(或类似的东西)。
  2. 由于您已经在使用string,因此您还应该学会使用vectorsplit最好写成:

    int split(string str, vector<string> &a, int max_size)
    {
        int ans=0;
        int k=0;
        while(k<str.length())
        {
            string next = nextstring(str,k);
    
            if(isalpha(next[0])!= 0)
            {
                ans++;
                a.append(next);
            }
            k += next.length();
         }
         return ans;
    }
    

答案 1 :(得分:0)

您的方法中的问题是识别字符串的结尾,因为c ++字符串中没有空终止符。考虑更新nextstring()以不同的方式查找字符串的结尾:

string nextstring(string str, int start_index) 
{
    ...
    if(start_index == str.size() || str[start_index] == ',' ) //<===
    {
        ans=" ";
    }
    ...
}

online demo

其他建议

请注意,返回空字符串并不是很好,实际上它应该为空以反映其实际值(例如“,,”)。你别无选择,因为否则你在调用函数中没有意义,以确定是否达到了字符串的结尾。但结果是你的所有字符串都有一个尾随空白。

当你递归调用函数添加char来构建返回字符串时,你可能会有相当大的开销。您可以考虑通过替换else部分来避免这种情况:

    ans=str.substr(start_index, str.find(',', start_index+1)-start_index);

但是,由于你没有尾随空白,你需要调整split()以适应它的方式来计算解析的字符总数:

    k=k+a[j].length()+1;  // +1 because there's no longer a trailing blank.  

Online demo