Parsing STL Strings

Submitted by date of submission user level 

Bulent Ozkir April 13, 2001 Beginner 

  

You can not use strtok directly to string::c_str() returned pointer. The reasons are depicted below. You can copy it to another allocation and then use strtok. But instead you should prefer STL string methods. A sample split function provided... 

  

>string s = "this is a string";

>char * ptr;

>ptr = strtok(s.c_str(), " ");

Bad move. strtok() will directly alter the data in the buffer being pointed to by c_str(). You should never use the pointer returned by c_str() to attempt to alter the original string. You are bypassing the class control mechanism. Or you may be altering the contents of a temporary buffer.

>while (ptr != NULL) {

>    cout << ptr << endl;

>    ptr = strtok(NULL, " ");

Here you are relying upon the contents of ptr which may or may not be pointing to the original string object's data. Also, strtok() will continue to modify the target string by inserting additional terminating NUL characters.

The cardinal rules are:

*Never* store the pointer returned by c_str() for later use. Always use it immediately to copy the string data to another buffer which you have allocated.

*Never* use the pointer returned by c_str() as the destination address for a data copy/write operation. Doing so will bypass the class interface, and possibly cause the class mechanism to lose control of the data. Consider the pointer returned by c_str() to be solely for immediate read only operations.

Avoid using external methods of altering/accessing a string object's data. Always use the member functions and overloaded operators provided by the class for manipulating the data.   

  

// The correct resolution... 

void split

    (string & text, string & separators, list & words)

 {

    int n = text.length();

    int start, stop;

    start = text.find_first_not_of(separators);

    while ((start >= 0) && (start < n)) {

       stop = text.find_first_of(separators, start);

       if ((stop < 0) || (stop > n)) stop = n;

       words.push_back(text.substr(start, stop - start));

       start = text.find_first_not_of(separators, stop+1);

       }

 }

 

--------------------------------------------------------------------------------

Bulent Ozkir is a Turkey based senior software engineer. He has worked as a senior support engineer for Microsoft from 1998 to 2000. In his over 5 years programming career he has been working on various programming technologies including VB, VC, Visual Interdev, JavaScript, ASP, HTML/DHTML, WMI, COM+, TCP/IP, IIS, SS3, MCIS25, ASP and SQL Server. His background includes B.A. Comp. Sc., MCSE + Internet and MCSD. See members area for more details.