2

Possible Duplicate:
Using strtok with a std::string

#include<iostream>
#include <string>
#include <string.h>

using namespace std;

int main()
{
    string s("hello hi here whola");
    string background;
    char *strval;

    char* tok = strtok_r(s.c_str()," ",&strval);
    while(tok !=NULL)
    {
    cout << tok <<"\n";
    if (tok == "&")
        background = tok;
    else
    {
        statements1;
        statement2.. ;
    }
    tok = strtok_r(NULL, " ",&strval);
    }

    return 0;
}

output:

new.cpp: In function ‘int main()’:
new.cpp:13:47: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
/usr/include/string.h:359:14: error:   initializing argument 1 of ‘char* strtok_r(char*, const char*, char**)’ [-fpermissive]
Community
  • 1
  • 1
Kanha
  • 43
  • 1
  • 6

3 Answers3

10

The s.c_str() returns a pointer to the const char to prevent you from modifying the backing up memory. You need to make a writable copy of this constant string say with strdup() function as strtok() really modifies the string that you are scanning for tokens.

Serge
  • 6,088
  • 17
  • 27
  • The problem lies in using c++ string class and char * type from C together. – Andro Oct 13 '12 at 14:48
  • @Andrej I am curious if the 'char *' type is forbidden in C++ :) – Serge Oct 13 '12 at 14:50
  • Well of course it is not, but mixing those types is the given case seems unnecessary and a little bit dangerous. – Andro Oct 13 '12 at 14:52
  • @Andrej I agree, but the question sounds as 'why it produces the error at compile time', not as 'please tell me how to write error-proof code in c++ using its 'native' API' – Serge Oct 13 '12 at 14:54
  • You are right once more but if some code compiles it does not automatically mean that is it good and can not produce and run-time errors. – Andro Oct 13 '12 at 14:58
1

strtok modifies its argument. This is not allowed with string.c_str() since it is a const char*

Also, even if it worked your if( tok == "&" ) will not work since tok is a char*, not a string, and you will thus be doing pointer and not content comparisons.

You would need to use strcmp()

Since you are using string, why not go for broke and use other c++ constructs?

stringstream ss(s);
string tmp; 
while (ss >> buf) {
    if( buf == "&" ) background = buf; // one wonders why
    cout << buf << '\n';
}
perh
  • 1,668
  • 11
  • 14
0

Your code is mixing C++ strings and couts with the C strtok_r function. It's not a good combination.

The immediate cause of your error is that c_str() returns a const char * while strtok() asks for a non-const char *. It wants to modify the string you pass as an argument, and you're not allowed to modify the string that c_str() returns.

If you want to do this C-style, then switch s to a char[].

char s[] = "hello hi here whola";
int background = 0;
char *strval;

char* tok = strtok_r(s, " ", &strval);
while (tok != NULL)
{
    printf("%s\n", tok);

    if (strcmp(tok, "&") == 0)
        background = 1;
    else
    {
        statement1;
        statement2;
        ...
    }

    tok = strtok_r(NULL, " ", &strval);
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578