コンマで文字列を分割します -- c++ フィールド と c++17 フィールド 関連 問題

Splitting a String up by comma












3
vote

問題

日本語

私はコンマで文字列を分割してベクトルを作成しようとしています。現在のコードは最初のインデックスに対して機能しますが、次の反復のために、イテレータはコンマを無視しますが、その後のものを理解しています。誰かがなぜそれがなぜですか?

<事前> <コード> getline(file,last_line); string Last_l = string(last_line); cout<< "String Lastline worked "<< Last_l <<endl; int end = 0; int start = 0; vector<string> linetest{}; for(char &ii : Last_l){ if( ii != ','){ end++; } else{ linetest.push_back(Last_l.substr(start,end)); // Disp(linetest); cout<< Last_l.substr(start,end) <<endl; end++; start = end; } }
英語

I am trying to split up a string by comma and populate a vector. The current code works for the first index, however, for the next iteration, the iterator ignores the the comma, but understands the one after that. Can anyone tell me why that is?

    getline(file,last_line);     string Last_l = string(last_line);     cout<< "String Lastline worked "<< Last_l <<endl;     int end = 0;     int start = 0;     vector<string> linetest{};      for(char &ii : Last_l){         if( ii != ','){             end++;         }         else{             linetest.push_back(Last_l.substr(start,end)); //            Disp(linetest);             cout<< Last_l.substr(start,end) <<endl;             end++;             start = end;         }      } 
</div
     
   
   

回答リスト

2
 
vote
vote
ベストアンサー
 

あなたのコードに基づいて、私はあなたが <コード> substr 。なお、2番目のインデックスは、最初のパラメータの後の文字のののカウント、の終了インデックスです。

それでも、elseの状態ではなく:

<事前> <コード> end++; // increment end index start = end; // reset start index

あなたは次のようなことをする必要があるでしょう:

<事前> <コード> start = end + 1; // reset start index end = 0; // reset count of chars

また、ループが終了した後、最後のコンマの後に残っている余分な文字列を追加することを忘れないでください。

<事前> <コード> linetest.push_back(Last_l.substr(start + end)); // all the remaining chars

これは全スニペットです:

<事前> <コード> for(char &ii : Last_l){ if( ii != ','){ end++; } else{ linetest.push_back(Last_l.substr(start,end)); start = end + 1; end = 0; } } linetest.push_back(Last_l.substr(start + end));

と働く demo 。

<コード> end <コード> count を変更した場合は、これが機能する理由がもっと意味があります。

また、<コード> using namespace std; を避けてください。

 

Based on your code, I think you are misunderstanding the parameters passed to substr. Note that the 2nd index is the count of characters after the first parameter, not the end index of the sub-string.

With that in mind, in the else condition, instead of:

end++;  // increment end index start = end;  // reset start index 

you would need to do something like:

start = end + 1;  // reset start index end = 0;  // reset count of chars 

Also, don't forget to add the extra string that's left over after the last comma, after the loop ends:

linetest.push_back(Last_l.substr(start + end));  // all the remaining chars 

Here's the full snippet:

for(char &ii : Last_l){         if( ii != ','){             end++;         }         else{             linetest.push_back(Last_l.substr(start,end));             start = end + 1;             end = 0;         } }  linetest.push_back(Last_l.substr(start + end)); 

and a working demo.

If you rename end to count it will make more sense why this works.

Also, please avoid using namespace std;, as it is considered bad practice.

</div
 
 
1
 
vote

だから、すでに良い答えがあります。

代替ソリューションを表示したい

文字列をトークンに分割することは非常に古いタスクです。利用可能な多くのソリューションがあります。すべて異なる特性があります。理解するのは難しいものもあります、いくつかは発達するのが難しい、いくつかはより複雑で、遅く、より速い、またはより柔軟であるかどうか。

選択肢

  1. 手作り、あなたのような、開発しやすいかもしれません。あなたの質問を見なさい。 。 。
  2. 古いスタイルを使用して<コード> std::strtok 機能。おそらく危険な。たぶん使用されるべきではなく、
  3. <コード> std::getline 。最も中古の実装しかし、実際には「誤用」であり、そうではない
  4. 専用の現代機能を使用して、この目的のために、最も柔軟で、STL環境とアルゴリズムの風景に適しています。しかし遅い
  5. 1つのコードで4つの例をご覧ください。

    <事前> <コード> end++; // increment end index start = end; // reset start index 0
 

So, a good answer is already given.

I want to show some alternative solutions

Splitting a string into tokens is a very old task. There are many many solutions available. All have different properties. Some are difficult to understand, some are hard to develop, some are more complex, slower or faster or more flexible or not.

Alternatives

  1. Handcrafted, like yours, maybe hard to develop and error prone. See your question . . .
  2. Using old style std::strtok function. Maybe unsafe. Maybe should not be used any longer
  3. std::getline. Most used implementation. But actually a "misuse" and not so flexible
  4. Using dedicated modern function, specifically developed for this purpose, most flexible and good fitting into the STL environment and algortithm landscape. But slower

Please see 4 examples in one piece of code.

#include <iostream> #include <fstream> #include <sstream> #include <string> #include <regex> #include <algorithm> #include <iterator> #include <cstring> #include <forward_list> #include <deque>  using Container = std::vector<std::string>; std::regex delimiter{ "," };   int main() {      // Some function to print the contents of an STL container     auto print = [](const auto& container) -> void { std::copy(container.begin(), container.end(),         std::ostream_iterator<std::decay<decltype(*container.begin())>::type>(std::cout, " ")); std::cout << ' '; };      // Example 1:   Handcrafted -------------------------------------------------------------------------     {         // Our string that we want to split         std::string stringToSplit{ "aaa,bbb,ccc,ddd" };         Container c{};          // Search for comma, then take the part and add to the result         for (size_t i{ 0U }, startpos{ 0U }; i <= stringToSplit.size(); ++i) {              // So, if there is a comma or the end of the string             if ((stringToSplit[i] == ',') || (i == (stringToSplit.size()))) {                  // Copy substring                 c.push_back(stringToSplit.substr(startpos, i - startpos));                 startpos = i + 1;             }         }         print(c);     }      // Example 2:   Using very old strtok function ----------------------------------------------------------     {         // Our string that we want to split         std::string stringToSplit{ "aaa,bbb,ccc,ddd" };         Container c{};          // Split string into parts in a simple for loop #pragma warning(suppress : 4996)         for (char* token = std::strtok(const_cast<char*>(stringToSplit.data()), ","); token != nullptr; token = std::strtok(nullptr, ",")) {             c.push_back(token);         }          print(c);     }      // Example 3:   Very often used std::getline with additional istringstream ------------------------------------------------     {         // Our string that we want to split         std::string stringToSplit{ "aaa,bbb,ccc,ddd" };         Container c{};          // Put string in an std::istringstream         std::istringstream iss{ stringToSplit };          // Extract string parts in simple for loop         for (std::string part{}; std::getline(iss, part, ','); c.push_back(part))             ;          print(c);     }      // Example 4:   Most flexible iterator solution  ------------------------------------------------      {         // Our string that we want to split         std::string stringToSplit{ "aaa,bbb,ccc,ddd" };           Container c(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});         //         // Everything done already with range constructor. No additional code needed.         //          print(c);           // Works also with other containers in the same way         std::forward_list<std::string> c2(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});          print(c2);          // And works with algorithms         std::deque<std::string> c3{};         std::copy(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {}, std::back_inserter(c3));          print(c3);     }     return 0; } 
</div
 
 

関連する質問

399  Nullを返すJava HashMap  ( Enum to string in modern c11 c14 c17 and future c20 ) 
現代C ++ 11 / C ++ 14 / C ++ 17と将来のC ++ 20の文字列への列挙 0123456789012345222 他のすべての同様の質問とは反対に、この質問は新しいC ++機能を使用することです。 2008 c C ++ EN...

2  Shared_PTRとしてのDETERで保護されたリソースをShared_PTRとして返す必要がある場合は、単一の書き込みと複数読み取りをデザインする方法  ( How to design a single write and multiple read when the protected resource need ) 
私はオブジェクトのマップに1つのライタのスレッドを書き込み、それぞれのリーダーオブジェクトがマップ上でのみ読み取り専用にするためにそれぞれのリーダーオブジェクトを持っています、私の放電設計は以下のようなものです、 <事前> <コード> class MyClas...

0  C ++ 17:ユーザー定義のコンストラクタは常に呼び出され、演算子+オーバーロードは子クラスのために機能しない  ( C17 user defined constructor is always called and operator overloading not w ) 
全体的に、符号なし番号をモジュール化するクラスを実装しています(符号なし型のラッパー)。私のクラスがこの条件を満たしたい: モジュラー数をすべて行うことができるすべての操作を行います。 下線付きのvalue_typeは符号なしタイプでなければなりませんが、テ...

0  テンプレートタイプC ++に基づく参照パラメータによるトグルパス  ( Toggle pass by reference parameter based on template type c ) 
"starts_with"関数を実装して、文字列がいくつかの接頭辞で始まるかどうかを確認しています。 std::string と<コード> std::string_view を交換可能に比較できるようにします。 std::string が引数として渡され...

2  2つのBoost :: Interusive :: Slistオブジェクトの間でノードを転送する方法  ( How to transfer nodes between two boostintrusiveslist objects ) 
2つの boost::intrusive::slist<boost::intrusive::cache_last<true>> オブジェクトの間でノードを転送するのに有効ですか?次のようなもの <事前> <コード> auto one = boost::int...

14  ローカル変数をconstまたは移動可能にする必要がありますか?  ( Should i make my local variables const or movable ) 
ローカルスコープ内のオブジェクトのマイデフォルトの動作は、 const にすることです。 e.g。: <事前> <コード> auto const cake = bake_cake(arguments); 私はこれが読みやすさを増加させることができるので、ほ...

2  C ++の切り離されたスレッドのバグ  ( C detached thread bug ) 
神秘的なバグを解決しようとしている1日を過ごした後、私はあなたの助けを求めます。 コードを実行するときは、「こんにちは3」の出力が重複している理由を理解していますか? <事前> <コード> #include <iostream> #include <futur...

5  カスタムアロケータから提供されている生メモリへのポインタを操作する方法(UBなし)?  ( How to work with pointers into raw memory provided by custom allocators without ) 
アロケータ対応コンテナを書き込もうとしています。 3つのオブジェクトのメモリのチャンクを割り当てたいとします。 <事前> <コード> T* chunk = std::allocator_traits<Allocator>::allocate(allocator...

21  C ++ Resutの結果<T、E>タイプ?  ( C equivalent of rusts resultt e type ) 
Std :: Implicatual :: C ++コードではオプションが好きですが、問題はVALUE_ORにオプションの値と同じ型になる必要があります。 intまたはエラーメッセージを含んでいるオプションであれば、これはうまく機能しません。 私は、値がそ...

0  Visual Studio 2019は次のように構成されています.C ++ 17ですが、C ++ 14のように見える  ( Visual studio 2019 is configured forc17 but it looks more like c14 ) 
次のコードをコンパイルした場合: <事前> <コード> #include <string_view> std::string_view strv{ "Test 1" }; このエラーを得ます: <事前> <コード> Error C2065 'str...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有