Forum: PC-Programmierung C++ durch vector iterieren bis gefunden


von Operator S. (smkr)


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?

von Peter II (Gast)


Lesenswert?

1
break;
;

von Thorsten (Gast)


Lesenswert?

break;

von Klaus W. (mfgkw)


Lesenswert?

Es gibt. z.B. ein break,
oder man baut den Abbruch gleich in den Vergleich im for ein...

von Vlad T. (vlad_tepesch)


Lesenswert?

müsste das nicht auch irgendwie so gehen:
1
auto it = std::find_if(  prefixes.begin(), prefixes.end(), 
2
                         [] (const std::string& s) { 
3
                            return s.find("text") != std::string::npos; 
4
                         } );

von Ronny S. (duselbaer)


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 :(

von Klaus W. (mfgkw)


Lesenswert?

Vlad T. schrieb:
> müsste das nicht auch irgendwie so gehen:

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

: Bearbeitet durch User
von Operator S. (smkr)


Lesenswert?

Danke an alle, break scheint die richtige Funktion zu sein, hatte 
fälschlicherweise im Kopf die soll man vermeiden.

find_if kannte ich noch nicht, danke für den Hinweis!

von Vlad T. (vlad_tepesch)


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.

von Klaus W. (mfgkw)


Lesenswert?

Mag sein, hängt aber davon ab was im Programm sonst so passiert - weiß 
man ja nicht.

von Klops (Gast)


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".

von Klops (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.