strtok function not splitting at the given delimiter

65 views Asked by At

Strtok is called like this:

char *headers = strtok(NULL, "\n\n");

on this string:

"Host: 172.27.34.56\nConnection: keep-alive\nDNT: 1\nUpgrade-Insecure-Requests: 1\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/*;q=0.8,application/signed-exchange;v=b3;q=0.7\ncp-extension-installed: Yes\nAccept-Encoding: gzip, deflate\nAccept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7\nRange: bytes=85-85\nIf-Range: Wed, 19 Jul 2023 19:15:56 GMT\n\n123"

but it splits on the first \n instead of \n\n. why?

2

There are 2 answers

0
Vivick On BEST ANSWER

std::strtok takes a list of delimiting characters as its second argument. It doesn't split by a string/substring.

Cf. The example on cppreference

If you're not against using std::string, you can make a tokUntil function as follows:

std::string tokUntil(std::string str, std::string delimiter) {
  auto pos = str.find(delimiter);
  return pos === std::string::npos ? str : str.substr(0, pos);
}
3
Fe2O3 On

As explained in comments and other answers, strtok() searches for any single instance of the characters listed in the second parameter.

Given the sample string, it appears you want to isolate the last field (following the double '\n').

Try:

    char *fldPtr = strrchr( headers, '\n' );
    if( fldPtr ) fldPtr += 1; // advance past that newline.

This will hunt from the end of the string toward the beginning.

Depending on the consistency of the source data format, you may want to add validation that this is giving what you expect. For instance:

    char *fldPtr = strrchr( headers, '\n' );
    if( fldPtr ) {
        if( fldPtr != headers && fldPtr[-1] == '\n' ) // got "\n\n" ???
            fldPtr += 1; // advance past that newline.
        else
            fldPtr = NULL;
    }