title: Finding substring within string C++ (find "el" in "hello")
body: <p>OK, so I was looking for an algorithm that could help me find a string within a substring.
  The code I was using before was from a <a href="https://stackoverflow.com/questions/2308696/substring-recursive-algorithm-not-working">similar question</a> but it doesn't do it.</p>
  
  <pre><code>// might not be exposed publicly, but could be
  int index_of(string const&amp; haystack, int haystack_pos, string const&amp; needle) {
    // would normally use string const&amp; 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&amp; h = haystack_pos;
  
    // preconditions:
    assert(0 &lt;= h &amp;&amp; h &lt;= 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);
  }
  </code></pre>
  
  <p>this doesn't return the start index of "el" on the string "hello" and I can't figure it out.</p>
  
  <p>EDIT:
  OK, let me show you a bit more of the code including some real-life examples:
  I'm trying to analyze a string that is a path to a file I want to sort in my filesystem.
  An input example is this:</p>
  
  <p>input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv</p>
  
  <p>when I try to parse this string to get the name of the by detecting the presence of SxxExx,I look for "s0","S0", etc (I know it's not the best implementation I was just trying to see if it worked and look at the code later). So when I use that input, what I get on the output is:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>intended output for aux: S04E01.720p.HDTV.x264-IMMERSE.mkv</p>
  
  <p>So as you can see it's just looking for any char that is in the string and stops, which also accounts for the multiple valid "found"s which should've been just the one.</p>
  
  <p>the full code where I'm trying to use this is:</p>
  
  <pre><code>bool StringWorker::isSeries(size_t &amp;i) {
  
      size_t found1, found2, found3, found4, found5, found6;
      found1 = input-&gt;find_last_of("S0"); //tried several find functions including the
      found2 = input-&gt;find_last_of("S1"); //index_of() mentioned above in the post
      found3 = input-&gt;find_last_of("S2");
      found4 = input-&gt;find_last_of("s0");
      found5 = input-&gt;find_last_of("s1");
      found6 = input-&gt;find_last_of("s2");
  
      if (found1 != string::npos) {
          if (input-&gt;size() - found1 &gt; 6) {
              string aux = input-&gt;substr(found1, input-&gt;size());
              cout &lt;&lt; "input:" &lt;&lt; *input &lt;&lt; endl;
              cout &lt;&lt; "aux: " &lt;&lt; aux &lt;&lt; endl;
              if (isalpha(aux.at(0)) &amp;&amp; isdigit(aux.at(1)) &amp;&amp; isdigit(aux.at(2))
                      &amp;&amp; isalpha(aux.at(3)) &amp;&amp; isdigit(aux.at(4))
                      &amp;&amp; isdigit(aux.at(5))) {
                  i = found1;
                  return true;
              }
          }
      }
      if (found2 != string::npos) {
          if (input-&gt;size() - found2 &gt; 6) {
              string aux = input-&gt;substr(found2, input-&gt;size());
              cout &lt;&lt; "input:" &lt;&lt; *input &lt;&lt; endl;
              cout &lt;&lt; "aux: " &lt;&lt; aux &lt;&lt; endl;
              if (isalpha(aux.at(0)) &amp;&amp; isdigit(aux.at(1)) &amp;&amp; isdigit(aux.at(2))
                      &amp;&amp; isalpha(aux.at(3)) &amp;&amp; isdigit(aux.at(4))
                      &amp;&amp; isdigit(aux.at(5))) {
                  i = found2;
                  return true;
              }
          }
      }
  
      if (found3 != string::npos) {
          if (input-&gt;size() - found3 &gt; 6) {
              string aux = input-&gt;substr(found3, input-&gt;size());
              cout &lt;&lt; "input:" &lt;&lt; *input &lt;&lt; endl;
              cout &lt;&lt; "aux: " &lt;&lt; aux &lt;&lt; endl;
              if (isalpha(aux.at(0)) &amp;&amp; isdigit(aux.at(1)) &amp;&amp; isdigit(aux.at(2))
                      &amp;&amp; isalpha(aux.at(3)) &amp;&amp; isdigit(aux.at(4))
                      &amp;&amp; isdigit(aux.at(5))) {
                  i = found3;
                  return true;
              }
          }
  
      }
      if (found4 != string::npos) {
          if (input-&gt;size() - found4 &gt; 6) {
              string aux = input-&gt;substr(found4, input-&gt;size());
              cout &lt;&lt; "input:" &lt;&lt; *input &lt;&lt; endl;
              cout &lt;&lt; "aux: " &lt;&lt; aux &lt;&lt; endl;
              if (isalpha(aux.at(0)) &amp;&amp; isdigit(aux.at(1)) &amp;&amp; isdigit(aux.at(2))
                      &amp;&amp; isalpha(aux.at(3)) &amp;&amp; isdigit(aux.at(4))
                      &amp;&amp; isdigit(aux.at(5))) {
                  i = found4;
                  return true;
              }
          }
  
      }
      if (found5 != string::npos) {
          if (input-&gt;size() - found5 &gt; 6) {
              string aux = input-&gt;substr(found5, input-&gt;size());
              cout &lt;&lt; "input:" &lt;&lt; *input &lt;&lt; endl;
              cout &lt;&lt; "aux: " &lt;&lt; aux &lt;&lt; endl;
              if (isalpha(aux.at(0)) &amp;&amp; isdigit(aux.at(1)) &amp;&amp; isdigit(aux.at(2))
                      &amp;&amp; isalpha(aux.at(3)) &amp;&amp; isdigit(aux.at(4))
                      &amp;&amp; isdigit(aux.at(5))) {
                  i = found5;
                  return true;
              }
          }
  
      }
      if (found6 != string::npos) {
          if (input-&gt;size() - found6 &gt; 6) {
              string aux = input-&gt;substr(found6, input-&gt;size());
              cout &lt;&lt; "input:" &lt;&lt; *input &lt;&lt; endl;
              cout &lt;&lt; "aux: " &lt;&lt; aux &lt;&lt; endl;
              if (isalpha(aux.at(0)) &amp;&amp; isdigit(aux.at(1)) &amp;&amp; isdigit(aux.at(2))
                      &amp;&amp; isalpha(aux.at(3)) &amp;&amp; isdigit(aux.at(4))
                      &amp;&amp; isdigit(aux.at(5))) {
                  i = found6;
                  return true;
              }
          }
  
      }
  
      return false;
  
  }
  </code></pre>
  
  <p>Can you see anything wrong here?</p>