Trouver des sous-chaîne dans la chaîne de C++ (trouver “el” dans “bonjour”)

OK, alors que je cherchais un algorithme qui pourrait m'aider à trouver une chaîne à l'intérieur d'une sous-chaîne.
Le code que j'utilisais était à partir d'un question similaire mais il ne le fait pas.

//might not be exposed publicly, but could be
int index_of(string const& haystack, int haystack_pos, string const& needle) {
  //would normally use string const& for all the string parameters in this
  //answer, but I've mostly stuck to the prototype you already have

  //shorter local name, keep parameter name the same for interface clarity
  int& h = haystack_pos;

  //preconditions:
  assert(0 <= h && h <= haystack.length());

  if (needle.empty()) return h;
  if (h == haystack.length()) return -1;
  if (haystack.compare(h, needle.length(), needle) == 0) {
    return h;
  }
  return index_of(haystack, h+1, needle);
}

int index_of(string haystack, string needle) {
  //sets up initial values or the "context" for the common case
  return index_of(haystack, 0, needle);
}

ce n'est pas revenir à l'index de début de "el" sur la chaîne "bonjour" et je ne peux pas le comprendre.

EDIT:
OK, permettez-moi de vous montrer un peu plus de code, y compris certains exemples de la vie réelle:
Je suis en train d'analyser une chaîne de caractères qui est un chemin vers un fichier je veux dans mon système.
Un exemple d'entrée est: est-ce

input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv

quand j'essaie de convertir cette chaîne pour obtenir le nom de la détection de la présence de SxxExx,je cherche des "s0","S0", etc (je sais c'est pas la meilleure mise en œuvre, j'essayais juste de voir si cela a fonctionné, et regarder le code plus tard). Alors, quand j'utilise cette entrée, ce que je reçois sur la sortie est:

input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv

aux: 0p.HDTV.x264-IMMERSE.mkv

input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv

aux: 1.720p.HDTV.x264-IMMERSE.mkv

input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv

aux: 264-IMMERSE.mkv

de sortie prévu pour aux: S04E01.De 720p.HDTV.x264-IMMERGER.mkv

Donc, comme vous pouvez le voir, c'est simplement à la recherche pour n'importe quel char qui est dans la chaîne et s'arrête, ce qui explique également les multiples valide "trouvé"s qui devraient ai juste le.

le code complet où je suis en train d'utiliser est la suivante:

bool StringWorker::isSeries(size_t &i) {
size_t found1, found2, found3, found4, found5, found6;
found1 = input->find_last_of("S0"); //tried several find functions including the
found2 = input->find_last_of("S1"); //index_of() mentioned above in the post
found3 = input->find_last_of("S2");
found4 = input->find_last_of("s0");
found5 = input->find_last_of("s1");
found6 = input->find_last_of("s2");
if (found1 != string::npos) {
if (input->size() - found1 > 6) {
string aux = input->substr(found1, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found1;
return true;
}
}
}
if (found2 != string::npos) {
if (input->size() - found2 > 6) {
string aux = input->substr(found2, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found2;
return true;
}
}
}
if (found3 != string::npos) {
if (input->size() - found3 > 6) {
string aux = input->substr(found3, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found3;
return true;
}
}
}
if (found4 != string::npos) {
if (input->size() - found4 > 6) {
string aux = input->substr(found4, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found4;
return true;
}
}
}
if (found5 != string::npos) {
if (input->size() - found5 > 6) {
string aux = input->substr(found5, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found5;
return true;
}
}
}
if (found6 != string::npos) {
if (input->size() - found6 > 6) {
string aux = input->substr(found6, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found6;
return true;
}
}
}
return false;
}

Pouvez-vous voir quelque chose de mal ici?

Quel est le problème avec std::string::find?
Quel est le problème avec std::search?
Fonctionne pour moi. Vous devez être à l'aide de la fonction à tort. Post un programme complet.
Il semblait correct pour moi aussi. Sauf que c'est un bon exemple de cas où la récursivité n'est pas une bonne solution. (Imaginez la recherche d'une sous-chaîne dans une chaîne d'un couple de millions de caractères.) Et il pourrait améliorer la condition de fin en utilisant h > haystack.size() - needle.size(); vous ne pouvez pas trouver une correspondance si la chaîne que vous êtes en train de regarder est plus petite que la sous-chaîne que vous essayez de faire correspondre.
Comme tout le monde vous dit, vous devez utiliser string::trouver. Mais aussi il n'y a pas de raison que votre index_of de fonction ne fonctionnent pas ainsi. Puisque vous ne pouvez pas obtenir la méthode de travail que vous devez faire quelque chose de mal. Quelque chose qui n'est pas dans le code ci-dessus. Essayez found1 = input->find("S0"); de nouveau, et si cela ne fonctionne toujours pas, essayez un débogueur. Découvrez ce qui se passe vraiment mal, parce que ce n'est pas ce que vous pensez qu'elle est.

OriginalL'auteur JackTakahashi | 2012-11-22