C++ durch vector iterieren bis gefunden

OP #4293776
Lesenswert?

Ich möchte durch einen std::vector iterieren, um ein bestimmtes Element 
zu finden, dieses zu benutzen und dann den Durchlauf abbrechen.

Im Konkreten Fall geht es darum:
1
std::vector<std::string> prefixes;
2
for(std::vector<std::string>::iterator it=prefixes.begin(); it!=prefixes.end(); ++it) {
3
    if( (*sigIt).find("text") != std::string::npos ) {
4
        cout << (*sigIt) << std::endl;
5
    }
6
}

Was gibt es für Möglichkeiten die iteration zu beenden, sobald der 
"text" gefunden wurde? Das stringstück kann irgendwo im string 
vorkommen, daher die find() Funktion, ist aber für die Frage irrelevant. 
"text" kann nur 1 mal im gesamten vector vorkommen.
Soll ich einfach it=prefixes.end() setzen, oder ist das unsauber?
#4293806
Lesenswert?

Da du ja schon die STL benutzt, warum nicht

#include <algorithm>

...

auto it = std::find_if(begin(prefixes), end(prefixes),
    [](std::string const & s) {
        return s.find("text") != std::string::npos;
    });

Algorithm bietet viel mehr, als man denkt - trotzdem wird vieles oft 
selbst neu erfunden :(
#4293960
Lesenswert?

Klaus W. schrieb:
> ja, aber erst mit C++11
> (aber nur wegen der lambda-Funktion; mit einer normalen Funktion als
> Test geht es auch mit altem C++)

ohne c++11, also mit normaler Funktion würde ich dieses Konstrukt nicht 
einsetzen, da finde ich, dass diese simple Funktionalität zu sehr im 
Code verteilt wird und man den Namensraum mit einer sinnlosen kleinen 
Funktion verschmutzt, die nur an dieser einen Stelle gebraucht wird.
Gast #4294110
Lesenswert?

Operator S. schrieb:
> Was gibt es für Möglichkeiten die iteration zu beenden, sobald der
> "text" gefunden wurde?
> for(std::vector<std::string>::iterator it

Wenn es so ähnlich sein soll:
1
for(const auto& s : prefixes)
2
{
3
  if(s.find("text") != std::string::npos)
4
  {
5
    std::cout << s << std::endl;
6
    break;
7
  }
8
}

Falls du es es als eigene Funktion haben willst - Name, mehrfacher 
Gebrauch, ... - vielleicht in dieser Art:
1
template <typename C>
2
auto find(const C& container, typename const C::value_type& token)
3
{
4
  return std::find_if(cbegin(container), cend(container),
5
    [&token](const auto& s)
6
  {
7
    return s.find(token) != std::string::npos;
8
  });
9
}
10

11
// ...
12

13
auto fIt = find(prefixes, "text");
14
if(fIt != cend(prefixes)) std::cout << *fIt << std::endl;

Die Innereien sind von oben geklaut. Als Template, damit es auch mit 
anderen Strings (wstring) funktioniert. Nur als Beispiel, man kann es 
sicher besser machen.

Klaus W. schrieb:
> ja, aber erst mit C++11

Stimmt schon, aber ich denke, dass man ohne expliziten Hinweis des TO 
vom aktuellen Standard ausgehen sollte - also momentan C++14 (minus 
einiger weniger Features, die noch nicht durchweg in den "großen 4" 
implementiert sind). Zumindest im Unterforum "PC-Programmierung".
Gast #4294416
Lesenswert?

Klops schrieb:
> Als Template, damit es auch mit anderen Strings (wstring) funktioniert.
> Nur als Beispiel, man kann es sicher besser machen.

Z.B. C::value_type::npos statt std::string::npos.
Macht zwar für den Compiler keinen Unterschied (npos ist in basic_string 
definiert), wäre aber sauberer.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren