質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

3954閲覧

string空白ありで何個目かの文字列を取り出す

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/02/11 05:15

空白ありで何個かの文字列を受け取り
何個目かの文字列を表示したいのですが
思い通りに動きません

条件は受け取る文字列はわからない例"okada saitou kimura isikawa"のようなランダムな文字列
この中で例えばkimuraだけを表示したい場合どうしたらいいですか?
あくまで文字列はランダムで受け取るので文字列の長さとかはわからない前提です

そこでこのようなコードを書いたのですがうまくいきません
打ち込むのがめんどくさいので受け取る文字列は打ち込んでしまってます
二個目のccccを取り出そうとしてます
まずfor文で二個目の空白の文字数をjに格納して
assignでj個目からfindでj以上の空白つまりccccの次の空白を受け取ろうとしたのですが
うまくいきません
なぜですか?
またいい例などはありますか?
できればstringを配列として(ss[5])扱わずにstringとしてお願いします

#include <string> using namespace std; int main(void) { string ss = "aaaaa bbb cccc dddddd ff gggg hhhhhhh"; string s1; __SIZE_TYPE__ j = 0; int i; for(i=0;i < 2;i++) { j += ss.find(' ',j); } cout << ss.assign(ss,j,ss.find(' ',j+1)) << endl; return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんなん書いてみた。

C++

1#include <string> 2 3template<typename String,typename OutputIterator> 4OutputIterator tokenize(const String& str, const String& delim, OutputIterator out) { 5 for ( typename String::size_type spos, epos = 0; 6 (spos = str.find_first_not_of(delim, epos)) != String::npos;) { 7 *out++ = str.substr(spos,(epos = str.find_first_of(delim, spos))-spos); 8 } 9 return out; 10} 11 12/* おためし */ 13#include <iostream> 14#include <vector> 15 16int main() { 17 using namespace std; 18 19 vector<string> input = { 20 "abc", 21 "a bb ccc", 22 " a bb ccc", 23 "a bb ccc ", 24 " a bb ccc dddd ", 25 " ", 26 "" 27 }; 28 for ( const auto& item : input ) { 29 using namespace std::literals::string_literals; 30 cout << '[' << item << "] -> "; 31 vector<string> out; 32 tokenize(item, " "s, back_inserter(out)); 33 for ( const auto& token : out ) { 34 cout << '[' << token << "] "; 35 } 36 cout << endl; 37 } 38 39} 40/* 実行結果 41[abc] -> [abc] 42[a bb ccc] -> [a] [bb] [ccc] 43[ a bb ccc] -> [a] [bb] [ccc] 44[a bb ccc ] -> [a] [bb] [ccc] 45[ a bb ccc dddd ] -> [a] [bb] [ccc] [dddd] 46[ ] -> 47[] -> 48*/

[追記] こっち↓の方がツブシが利くかなー...

C++

1template<typename String,typename Function> 2void tokenize(const String& str, const String& delim, Function&& fun) { 3 for ( typename String::size_type spos, epos = 0; 4 (spos = str.find_first_not_of(delim, epos)) != String::npos;) { 5 fun(str.substr(spos,(epos = str.find_first_of(delim, spos))-spos)); 6 } 7} 8 9/* おためし */ 10#include <iostream> 11#include <string> 12 13int main() { 14 using namespace std; 15 string input[] = { 16 "abc", 17 "a bb ccc", 18 " a bb ccc", 19 "a bb ccc ", 20 " a bb ccc dddd ", 21 " ", 22 "" 23 }; 24 for ( const auto& item : input ) { 25 using namespace std::literals::string_literals; 26 cout << '[' << item << "] -> \n "; 27 int count = 0; 28 auto print = [&](const string& token) { cout << ++count << '[' << token << "] ";}; 29 tokenize(item, " "s, print); 30 cout << endl; 31 } 32 33}

投稿2018/02/11 08:35

編集2018/02/11 11:26
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/02/12 02:10

ありがとうございました
guest

0

assign()ではなくsubstr()を使う方法でコーディングしてみました。
参考サイト:C++ 区切り文字/文字列による文字列の分割(split)std::string/文字列ポインタ

C++

1#include <iostream> 2#include <string> 3using namespace std; 4 5string GetSplittedStrAt(string input_str, string delimiter, int number) 6{ 7 int delim_length = delimiter.length(); 8 string::size_type pos = 0; 9 string::size_type offset = 0; 10 for(int i = 0; i < number + 1; i++) { 11 pos = input_str.find(delimiter, offset); 12 if (pos == string::npos) { 13 return input_str.substr(offset); 14 } 15 if (i < number) { 16 offset = pos + delim_length; 17 } 18 } 19 return input_str.substr(offset, pos - offset); 20} 21 22int main(void) 23{ 24 string ss = "aaaaa bbb cccc dddddd ff gggg hhhhhhh"; 25 string ss_2 = GetSplittedStrAt(ss, " ", 2); // Output: cccc 26 cout << ss_2 << std::endl; 27 28 // 参考 29 string ss_0 = GetSplittedStrAt(ss, " ", 0); 30 string ss_1 = GetSplittedStrAt(ss, " ", 1); 31 // ss_2は定義済み 32 string ss_3 = GetSplittedStrAt(ss, " ", 3); 33 string ss_4 = GetSplittedStrAt(ss, " ", 4); 34 string ss_5 = GetSplittedStrAt(ss, " ", 5); 35 string ss_6 = GetSplittedStrAt(ss, " ", 6); 36 cout << ss_0 << endl; 37 cout << ss_1 << endl; 38 cout << ss_2 << endl; 39 cout << ss_3 << endl; 40 cout << ss_4 << endl; 41 cout << ss_5 << endl; 42 cout << ss_6 << endl; 43 /* 44 Output: 45 aaaaa 46 bbb 47 cccc 48 dddddd 49 ff 50 gggg 51 hhhhhhh 52 */ 53 return 0; 54} 55

投稿2018/02/11 05:48

編集2018/02/12 02:10
K_S_

総合スコア419

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/02/11 06:15

ありがとうございます ccccの後に一つ空白が入るのはどうにかできませんでしょうか? お願いします
退会済みユーザー

退会済みユーザー

2018/02/24 12:10

気づくのが遅れすみません ありがとうございました とてもわかりやすいです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問