-2

Trying to relearn C/C++ why is it when I run this:

char* tmp;

while ((tmp =  strtok(itr->c_str(),' ')) != NULL ) {
          std::string s(tmp);
           cout << "S " << s<< endl;
}

I obtain this:

/usr/include/c++/4.8.3/bits/basic_string.h:437:7: note:   candidate expects 0 arguments, 1 provided

It is either that or I do not have enough arguments. I know tmp is not NULL because I am checking it in my while loop. It also happens when I try string s = string(tmp);

I see the documentation and I thought I copied it down similarly except for my needs. I am obviously missing something.

Any feed back please?

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
Kyle Calica-St
  • 2,629
  • 4
  • 26
  • 56
  • 2
    Please post the *full* error message, preferably with an [MCVE](http://stackoverflow.com/help/mcve) that we can copy, paste, and run. – chris Apr 12 '15 at 23:45
  • 1
    your error might not be in this code segment. –  Apr 12 '15 at 23:48
  • Given that you've accepted Ben's answer, I am extremely curious what the rest of the error is, because it currently makes no sense. – chris Apr 13 '15 at 00:05

2 Answers2

2

You can't use strtok on a constant string because it actually overwrites delimiters with NUL terminators, so this won't work

strtok(itr->c_str(),' ')

Your loop also doesn't perform the right steps to get multiple tokens from the same string.

Since you want each token copied into a separate string instance anyway, consider using std::string's find member functions along with substr, and avoiding strtok completely. Many different examples given on the canonical question about splitting a std::string The exact approach I suggested is seen in one of the answers there.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

I agree with Ben that there are better ways to do this, but FWIW will show how to fix your code. Note in particular the use of &s[0] (in your case &(*itr)[0]) to get a (writable) char* into the string, and that after the first call a nullptr must be passed to subsequent strtok invocations.

#include <iostream>
#include <cstring>

int main()
{
    std::string s = "first second third fourth fifth sixth";
    for (char* tmp = std::strtok(&s[0], " "); tmp;
         tmp = std::strtok(nullptr, " "))
    {
        std::string field(tmp);  // can "<< tmp <<" below directly....
        std::cout << "S " << field << '\n';
    }
}

I believe C++11 was the first C++ Standard to mandate a contiguous buffer for std::string, so the code above is not guaranteed to work with earlier versions, though in practice all std::string implementations I've ever heard of used contiguous memory (as distinct from STL's rope).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Yes, this takes care of both problems I saw, plus the separator-should-be-string-not-single-character error. I would suggest using different names for the two different `std::string` variables, to avoid confusion. – Ben Voigt Apr 13 '15 at 00:43
  • @BenVoigt: oh - hadn't even noticed the dual uses of `s` - cheers. – Tony Delroy Apr 13 '15 at 00:59