Hallo,
ich nutze eine Funktion die heißt StringFind und ist wie folgt
definiert:
1
int StringFind(
2
string string_value, // string in which search is made
3
string match_substring, // what is searched
4
int start_pos=0 // from what position search starts
5
);
Nun möchte ich automatisiert ein Textfile nach einem bestimmten String
durchsuchen z.B. "Tigerente", dabei soll aber auch "tIgerEnte" oder
"tiGERente" gefunden werden.
Gibt es eine Möglichkeit, wie ich nach einem bestimmten String suchen
kann, aber dabei die Groß-/Kleinschreibung der einzelnen Buchstaben
nicht berücksichtigen brauche?
Mit ist schon klar wie ich ein einzelnes Zeichen von Groß- in
Kleinschreibung umwandeln kann, aber wie ich einen String suche, von dem
ich noch nichtmal weiß, wo die Buchstaben groß/kleingeschrieben sind,
weiß ich nicht.
Mir fällt hier nur folgendes ein (kann ich gerade nicht
programmierteschnisch umschreiben):
1
int SeachString(string string_value, string match_substring, int start_pos)
2
{
3
if(1.Buchstabe von match_substring gross ODER klein gefunden)
4
{
5
merke die position = pos dieses Buchstaben
6
if(2.Buchstabe von match_substring gross ODER klein gefunden)
7
}
8
if(3.Buchstabe von match_substring gross ODER klein gefunden)
9
if(x.Buchstabe von match_substring gross ODER klein gefunden)
Ist die Programmiersprache, in der das geschrieben ist, geheim?
Ansonsten wäre eine einfache Lösung, beide Strings z.B. komplett in
Großbuchstaben zu konvertieren und dann erst die Suche machen.
Rolf Magnus schrieb:> Ist die Programmiersprache, in der das geschrieben ist, geheim?
Scheint eine mischung aus c++ und pseudocode zu sein, mit
1
usingnamespacestd;
:( und
1
#include<string>
> Ansonsten wäre eine einfache Lösung, beide Strings z.B. komplett in> Großbuchstaben zu konvertieren und dann erst die Suche machen.
Finde ich inperformant, und unschön. Ich würde eine Vergleichsfunktion
übergeben.
Ungetestet:
In ASCII unterscheiden sich Groß- und Kleinbuchstaben nur durch ein
bit...
Ein bitweises OR mit 0b00100000 mach aus jedem Zeichen einen
Kleinbuchstaben.
Hierzu gibt es in C bereits Funktionen:
http://gd.tuwien.ac.at/languages/c/cref-mleslie/master_index.html
Zuerst beide Strings in Kleinbuchsstaben umwandeln:
=> tolower function. Convert an uppercase character to lowercase.
Und dann den Substring suchen
=> strstr function. Search a string for a substring.
oder mit
=> strtok function. this function splits a string into tokens.
@Max H. (hartl192)
>In ASCII unterscheiden sich Groß- und Kleinbuchstaben nur durch ein>bit...>Ein bitweises OR mit 0b00100000 mach aus jedem Zeichen einen>Kleinbuchstaben.
Ein String besteht aber nicht nur aus Buchstaben, erst recht nicht nur
aus Großbuchstaben. Du müsstest als jedes Zeichen prüfen, ob es sich so
in klein wandeln liese.
Da kannst Du gleich tolower nehmen.
Außerdem sind Umlaute auch Buchstaben, aber nicht Teil von ASCII.
Daniel A. schrieb:>> Ansonsten wäre eine einfache Lösung, beide Strings z.B. komplett in>> Großbuchstaben zu konvertieren und dann erst die Suche machen.>> Finde ich inperformant, und unschön. Ich würde eine Vergleichsfunktion> übergeben.
Wenn man dann schon C++ hat, bietet sich an, ein Template draus zu
machen, gerade auch für die Performance.
Rolf Magnus schrieb:> Außerdem sind Umlaute auch Buchstaben, aber nicht Teil von ASCII.
Und noch schöner: mein Liebling das 'ß', wie in Grossbuchstaben?
Beispiele die nur in USA funktionieren sind praktisch völlig wertlos.
Georg
Georg schrieb:> Rolf Magnus schrieb:>> Außerdem sind Umlaute auch Buchstaben, aber nicht Teil von ASCII.>> Und noch schöner: mein Liebling das 'ß', wie in Grossbuchstaben?
Da gibt's ja immerhin noch die Möglichgkeit einer Sonderbehandlung,
indem man halt zwei Zeichen draus macht. Aber spätestens umgekehrt ist
man dann aufgeschmissen (MASSE -> masse oder maße?).
Das wäre doch ein klassischer Fall für
Reguläre Ausdrücke (RegEx - lib).
Gibt es sowas nicht für C/C++ ?
In meiner Sprache würde das so aussehen :
Print Match$("(?i)Tigerente*[A-Za-z0-9]{1,}", "Ich habe eine tIGerEntE
zu Hause")
Georg schrieb:> Beispiele die nur in USA funktionieren sind praktisch völlig wertlos.
Da stimme ich zu.
Rolf Magnus schrieb:> Georg schrieb:>> Rolf Magnus schrieb:>>> Außerdem sind Umlaute auch Buchstaben, aber nicht Teil von ASCII.>>>> Und noch schöner: mein Liebling das 'ß', wie in Grossbuchstaben?>> Da gibt's ja immerhin noch die Möglichgkeit einer Sonderbehandlung
ja... und was machst du mit allen anderen "Sonderbuchstaben"?
É È ô à usw. ? Allein für den "latin_1"-Bereich gibt es mind. 70 solcher
"Sonderbuchstaben". Die sind nicht Teil von ASCII... wie viele
sonderbehandlungen willst du machen?
Daniel A. schrieb:> Finde ich inperformant, und unschön.
So, du "findest" das es unperformant ist... ich "finde" auch das unsere
regierung unperformant und unschön ist, aber dieses "empfinden"
interessiert nicht! Ist es unperformant, oder nicht? Hast du das mal
getestet? Und was gilt denn als "unperformant"? Da hast du ja bestimmt
auch mal Zahlenwerte um das vergleichen zu können.
Und warum etwas neu erfinden, was es in den std. libs gibt? Die
entsprechenden Funktionen sind mit sicherheit nicht in den std. libs
gelandet, weil sie so super unperformant sind...
An den TO:
Wenn du nicht dazu gezwungen bist C oder C++ zu verwenden, dann nimm
Python für sowas. Da ist die Stringhandhabung um ein vielfaches
einfacher als in C oder C++.
1
# Funktioniert mit Python 2.7 und Python 3.x
2
MyString="Hallo liebes Mikrocontroller.net-Forum"
3
StringToFind="Bes mIkrO"
4
IsFound=False
5
6
if(StringToFind.lower()inMyString.lower()):
7
IsFound=True
8
9
print(IsFound)
Heinz Brill schrieb:> Das wäre doch ein klassischer Fall für> Reguläre Ausdrücke (RegEx - lib).
Nicht böse gemeint, aber:
"Some people, when confronted with a problem, think: 'I know, I'll use
regular expressions.' Now they have two problems." - Jamie W. Zawinski
:P
Aber ja, RegEx wäre auch eine Möglichkeit.
Sandra schrieb:> Nun möchte ich automatisiert ein Textfile nach einem bestimmten String> durchsuchen z.B. "Tigerente", dabei soll aber auch "tIgerEnte" oder> "tiGERente" gefunden werden.
Das folgende Programm sagt dir, ob deine Tigerente in der Datei steckt,
oder nicht.
>> Ansonsten wäre eine einfache Lösung, beide Strings z.B. komplett in>> Großbuchstaben zu konvertieren und dann erst die Suche machen.>>Finde ich inperformant, und unschön. Ich würde eine Vergleichsfunktion>übergeben.>>Ungetestet:>int16_t compareFunc2(char a,char b){> if(a>='A'&&a<='Z') a=a-'A'+'a';> if(b>='A'&&b<='Z') b=b-'A'+'a';
Also ich finde Deine Lösung ist weder schöner noch performanter!
Wenn es wirklich um Performanz geht, sollte man ohnehin einen anderen
Algorithmus verwenden. Hier sind Beispiele:
http://de.wikipedia.org/wiki/String-Matching-Algorithmus#.C3.9Cbersicht
Der in diesem Thread bereits in verschiedenen Varianten vorgeschlagene
Algorithmus wird dort als "naiv" bezeichnet und stellt in den
allermeisten Fällen die am wenigsten performante Lösung dar.