🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

C++

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

Q&A

解決済

2回答

3238閲覧

C/C++ STL algorithm find_if の使い方がわからない。

yukkuri_55

総合スコア262

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

C++

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

0グッド

0クリップ

投稿2019/10/23 11:43

STL を使って vector<string> に格納したテキストのないようから
特定の文字列を含んでいる場合、真を返し、イテレータで受け取り
そのイテレータをインクリメンタルすることで、特定の文字列を含んだ
内容を全部、出力した。
ここでは、特定の文字列を 「<a href="https://tsundora.com/」としている

「実行結果」
[INFO]STEP2: 0001/0001

STEP3 各トップページから番号を取り出します。
(INFO) 検索 HIT <ul id="menu-%e3%83%a1%e3%82%a4%e3%83%b3%e3%83%a1%e3%83%8b%e3%83%a5%e3%83%bc" class="menu"><li id="menu-item-243822" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-243822"><a href="https://tsundora.com/alist">繧「繝九Γ螢∫エ吶Μ繧ケ繝・/a></li>
FIND:<ul id="menu-%e3%83%a1%e3%82%a4%e3%83%b3%e3%83%a1%e3%83%8b%e3%83%a5%e3%83%bc" class="menu"><li id="menu-item-243822" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-243822"><a href="https://tsundora.com/alist">繧「繝九Γ螢∫エ吶Μ繧ケ繝・/a></li>

FIND:<li id="menu-item-112236" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-112236"><a href="https://tsundora.com/artist">繧「繝シ繝・ぅ繧ケ繝・/a></li>

FIND:<li id="menu-item-175902" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-175902"><a href="https://tsundora.com/pools">繝励・繝ォ</a></li>

FIND:<li id="menu-item-112659" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-112659"><a href="https://tsundora.com/keyword">莠コ豌励Ρ繝シ繝・/a></li>

FIND:<li id="menu-item-43608" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-43608"><a target="_blank" href="http://kjgame.sakura.ne.jp/rank/animewall/ranklink.cgi?id=otachan">螢∫エ吶Λ繝ウ繧ュ繝ウ繧ー</a></li>

FIND:<div class="clear"></div>

FIND:</div><!--//header_menu-->

FIND: <div class="clear"></div>

FIND: <div class="clear"></div>

FIND: </div><!--//container-->

FIND: </div><!--//header_top_cont-->

FIND:<a href="https://tsundora.com" title="tsundora.com"><img src="https://tsundora.com/wp-content/themes/TsundoraTheme/images/logo.svg" alt="tsundora.com"></a>

FIND:<h2>鬮倩ァ」蜒丞コヲ繝サ鬮倡判雉ェ縺ェ繧「繝九Γ・・ご繝シ繝螢∫エ・/h2>

=========================================================================================

以下がソースコード(抜粋)です。

cpp

1 2bool 検索(string szString) 3{ 4 char* p; 5 char szBuff[DEF_BUFFSIZE]; 6 strcpy_s(szBuff, szString.c_str()); 7 p = strstr(szBuff, "<a href=\"https://tsundora.com/"); 8 if (p) 9 { 10 printf("(INFO) 検索 HIT %s", szBuff); 11 } 12 if (p) 13 return true; 14 else 15 return false; 16} 17//=============================================== 18// 各トップページから番号を取り出す 19void Dic_Step3() 20{ 21 printf("STEP3 各トップページから番号を取り出します。\n"); 22 23 24 vector<string> vText; 25 26 int i; 27 for (i = 1; i <= g_NUM; i++) 28 { 29 char szFile[80]; 30 sprintf_s(szFile, "top%04d%s", i, ".dat" ); 31 32 // ファイルの内容を vText に保存 33 Dic_ReadFile(szFile, &vText); 34 vector<string>::iterator p; 35 36 // テキストの内容が vText に入っているので 関数「検索」で真偽判定をしてループで 37 // 「検索」で true の値を返す イテレータの内容を出力する。 38 p = find_if(vText.begin(), vText.end(), 検索 ); 39 if (p != vText.end()) 40 { 41 while (p != vText.end()) 42 { 43 char szBuff[DEF_BUFFSIZE]; 44 strcpy_s(szBuff, p->c_str()); 45 if( strlen(szBuff) > 20 ) 46 printf("[FIND]:%s\n", szBuff ); 47 p++; 48 } 49 } 50 vText.clear(); 51 } 52} 53

(INFO) 検索 HIT が一件しかでなくて、特定の文字列を含んでいない文字列も
イテレータが運んでくるので、どこが悪いのでしょうか?

環境
OS:Windows10 Pro
IDE:Visual Studio 2019 Commnity
C/C++ STL
#include<algorithm>

望む結果
(INFO 検索 HIT: xxxx 1件目
(INFO 検索 HIT: xxxx 2件目
..
..
(INFO 検索 HIT: xxx 終了
特定の文字列を含んだ文字列のみを抽出したい。
それをイテレータを使って、先頭から末尾まで表示(格納)したい。

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

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

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

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

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

guest

回答2

0

ベストアンサー

C++ なら、char * など使わずに string を使ったほうが良いのでは?

C++

1#include <iostream> // cout 2#include <sstream> // ostringstream 3#include <fstream> // ifstream 4#include <string> // getline 5#include <vector> // vector 6#include <iomanip> // setfill, setw 7using namespace std; 8 9const int g_NUM = 3; 10 11bool 検索(const string& s) 12{ 13 return s.find("<a href=\"https://tsundora.com/") != string::npos; 14} 15 16bool Dic_ReadFile(const string& fname, vector<string>& vText) 17{ 18 ifstream ifs(fname); 19 if (!ifs) return false; 20 string s; 21 while (getline(ifs, s)) vText.push_back(s); 22 return true; 23} 24 25int main() 26{ 27 for (int i = 1; i <= g_NUM; i++) { 28 ostringstream oss; 29 oss << "top" << setfill('0') << setw(4) << i << ".dat"; 30 vector<string> vText; 31 if (!Dic_ReadFile(oss.str(), vText)) break; 32 for (vector<string>::iterator p = vText.begin(); p != vText.end(); ++p) 33 if (検索(*p)) cout << "[FIND]:" << *p << '\n'; 34 } 35}

STL の find_if ではなく、string::find を使ったので、
ご希望のものではないかもしれませんが。

追記
長さが 20以上という条件が要るんでしょうか?

C++

1 if (検索(*p) && p->size() > 20) cout << "[FIND]:" << *p << '\n';

追記2
STL の find_if 使って main を書き直してみました。

C++

1#include <algorithm> // find_if 2 3int main() 4{ 5 for (int i = 1; i <= g_NUM; i++) { 6 ostringstream oss; 7 oss << "top" << setfill('0') << setw(4) << i << ".dat"; 8 vector<string> vText; 9 if (!Dic_ReadFile(oss.str(), vText)) break; 10 vector<string>::iterator p = vText.begin(); 11 for (; (p = find_if(p, vText.end(), 検索)) != vText.end(); ++p) 12 if (p->size() > 20) cout << "[FIND]:" << *p << '\n'; 13 } 14}

投稿2019/10/23 17:40

編集2019/10/24 13:19
kazuma-s

総合スコア8224

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

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

yukkuri_55

2019/10/24 11:04

長さ20というのは、なぜか3文字とかをひろってくるので、削除しようとして追加しました。 教えていただいたソースコードを元にして修正したところ、 ぶじ、目的が達成できました。 ありがとうございました。
guest

0

find_ifは、条件に合致する最初の要素を返すため複数件の抽出には向きません。
copy_ifを用いましょう。

c++

1vector<string> result; 2result.reserve(vText.size()); 3 4copy_if(vText.begin(), vText.end(), back_inserter(result), 検索); 5for(const auto& str : result) { 6 if(str.length() > 20) 7 printf("[FIND]:%s\n", str.c_str() ); 8}

投稿2019/10/23 15:14

asm

総合スコア15149

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

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

yukkuri_55

2019/10/24 11:05

kazuma-s様のご回答により解決できましたので、また機会がありましたら お答えくださると助かります。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問