如何用strtok按 分割HTTP响应,分离头部与正文?
问题描述
我尝试分割下面这个HTTP响应字符串:
#define INVALID_NUMBER_PARAMS "HTTP/1.1 400 Bad Request content-type: text/html content-encoding: identity content-length: 59 Could not fulfill request due to wrong number of paramaters"
使用自定义的splitString函数,想通过**空行(两个连续换行)**分割出头部和正文两部分:
void splitString(struct Arr* arr, char* str, char* delim) { if (!initialAlloc(arr)) { exit(1); } char* subStr = strtok(str, delim); while (subStr != NULL) { addToArr(arr, subStr); subStr = strtok(NULL, delim); } }
但实际调用时,函数会在每个头部行的末尾就触发分割,而非正文起始的空行位置。我试过转义分隔符,还试过\r\r、\n\n等多种变体,都出现随机分割的问题——比如用"\\r\\r"作为分隔符时,输出变成:
str: http/1.1 400 bad str: equest content-type: text/html content-encoding: identity content-length: 59 could not fulfill str: equest due to w str: ong numbe str: of pa str: amate str: s
我的调用代码如下:
splitString(&split, tempStr, "\\r\\r"); for (int x = 0; x < split.currentSize; x++) { printf("str: %s\n", split.cArr[x]); }
请问怎么修改才能让函数按空行分割,得到包含所有头部的元素和包含正文的元素这两个结果?
解决方案
核心问题:strtok的工作逻辑
strtok会把分隔符字符串里的每个字符当作独立分隔符,而非把整个字符串作为一个完整分隔符。比如传"\n\n"时,它会把单个\n当作分割标记,所以每一行的换行都会触发分割,这就是头部被拆成多行的原因。
修改后的分割函数
不能直接用strtok,需要自己实现按完整子串分割的逻辑,用strstr定位分隔符位置即可:
#include <string.h> #include <stdlib.h> void splitString(struct Arr* arr, char* str, char* delim) { if (!initialAlloc(arr)) { exit(1); } char* currentPos = str; size_t delimLen = strlen(delim); while (1) { // 定位分隔符的位置 char* delimPos = strstr(currentPos, delim); if (delimPos == NULL) { // 无分隔符,将剩余内容加入数组(跳过空字符串) if (*currentPos != '\0') { addToArr(arr, currentPos); } break; } // 临时将分隔符开头替换为\0,提取子串 *delimPos = '\0'; addToArr(arr, currentPos); // 跳过分隔符,移动到下一段起始位置 currentPos = delimPos + delimLen; } }
调用注意事项
- 传入正确的分隔符:
- 若字符串是Unix换行格式(
\n),传"\n\n" - 若是Windows换行格式(
\r\n),传"\r\n\r\n" - 不要加多余转义,比如不要写成
"\\n\\n",这会被解析成反斜杠加n,而非换行符
- 若字符串是Unix换行格式(
- 该函数会修改原字符串(替换了
\0),若需保留原字符串,要先复制一份再传入。
示例调用
// 假设字符串是Unix换行格式 splitString(&split, tempStr, "\n\n"); for (int x = 0; x < split.currentSize; x++) { printf("str: %s\n", split.cArr[x]); }
执行后会得到两个元素:第一个是所有HTTP头部内容,第二个是正文内容。
内容的提问来源于stack exchange,提问作者user18043747
相关产品推荐
相关产品推荐

