I’ve got a function that splits up a string into various sections and then parses them, but when converting a string to char* I get a malformed output.
int parseJob(char * buffer)
{ // Parse raw data, should return individual jobs
const char* p;
int rows = 0;
for (p = strtok( buffer, "~" ); p; p = strtok( NULL, "~" )) {
string jobR(p);
char* job = &jobR[0];
parseJobParameters(job); // At this point, the data is still in good condition
}
return (1);
}
int parseJobParameters(char * buffer)
{ // Parse raw data, should return individual job parameters
const char* p;
int rows = 0;
for (p = strtok( buffer, "|" ); p; p = strtok( NULL, "|" )) { cout<<p; } // At this point, the data is malformed.
return (1);
}
I don’t know what happens between the first function calling the second one, but it malforms the data.
As you can see from the code example given, the same method to convert string to char* is used and it works fine.
I’m using Visual Studio 2012/C++, any guidance and code examples will be greatly appreciated.
The “physical” reason your code does not work has nothing to do with
std::stringor C++. It wouldn’t work in pure C as well.strtokis a function that stores its intermediate parsing state in some global variable. This immediately means that you cannot usestrtokto parse more than one string at a time. Starting the second parse session before finishing the first would override the internal data stored by the first parse session, thus ruining it beyond repair. In other words,strtokparse sessions must not overlap. In your code they do overlap.Also, in C++03 the idea of using
std::stringwithstrtokdirectly is doomed from the start. The internal sequence stored instd::stringis not guaranteed to be null-terminated. This means that generally&jobR[0]is not a C-string. It can’t be used withstrtok. To convert astd::stringto a C-string you have to usec_str(). But C-string returned byc_str()is non-modifiable.In C++11 the null-termination is supposed to be visible through the
[]operator, but still there seems to be no requirement to store the terminator object contiguously with the actual string, so&jobR[0]is still not a C-string even in C++11. C-string returned byc_str()ordata()is non-modifiable.