2016-10-31 1 views
0

コンマで区切られた値の文字列をスペースなしで入力するコードを記述しています(例:my,name,is,jack)。最初に関数を記述する必要がありましたstrtokとsplitの再実装をデバッグします

string nextstring(string str, int start_index) 

開始インデックスに応じて最初の文字列から単一の「値」を返します。問題の第2の部分は、最初の文字列のすべての値を識別し、文字列配列に入れ、次いで、アレイに格納された値の合計数を返す関数

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; 
} 
+4

、このような問題を解決するための適切なツールは、あなたのデバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。最低限、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、その問題を再現するためのデバッガ。 –

+0

推奨: 'ans =" ";;'を返すのではなく、 'ans =" ";'を返します。空の文字列は、空白文字列としてスペース文字列よりも簡単に認識できます。 – user4581301

+0

もう1つの推奨事項:質問を投稿すると、すべてのユーザー入力が削除され、不正な動作を引き起こす一連の入力にプログラムが強制的に実行されます。これにより、テスト入力で推測するのではなく、見ているものを正確に見ることができます。 – user4581301

答えて

0

あなたの問題がjからwhile(j<max_size){...}リードがmax_sizeまでインクリメントされるということであるようです。行a[j]= nextstring(str,k);は、実際には悪いあなたの文字列の外にある値を読んでいるところです!

while(j<max_size){...}while(j<max_size && k<str.length()){...}に変更すると、コードがうまく動作しているようです。それとは別に


  1. kは2倍にする理由がありません! int(または類似のもの)である必要があります。
  2. 既にstringを使用しているので、vectorも使用することを学ぶ必要があります。あなたのアプローチでの問題は、C++の文字列にはNULL終端がないので、文字列の末尾を識別することである

    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; 
    } 
    
+0

私は 'k'を' size_t'にすることをお勧めします。なぜなら、最も不気味な大きな文字列でさえインデックスを作成するのに十分な大きさであり、負のインデックスの可能性を許容する点はないからです。 – user4581301

0

splitは、より良いとして書かれています。別の方法で、文字列の末尾を探すためにnextstring()を更新するために、考えてみましょう:

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

online demo

追加勧告

注ときに空白文字列を返すために非常に良いではないこと現実の価値を反映するためには空でなければなりません(例えば、「,,」)。文字列の終わりに達したかどうかを判断するために、呼び出し関数に意味を持たないため、選択肢がありません。しかし、結果はあなたの弦にすべて空白が残っています。

戻り文字列を作成するためにcharを追加する関数を再帰的に呼び出すと、かなりのオーバーヘッドが発生する可能性があります。あなたが他の部品を交換することにより、これを回避することを検討することができなかった:

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

関連する問題