为什么strtok()没有选择'?'线上的人物?

时间:2016-12-11 19:49:46

标签: c strtok

以下是我在codeblocks版本13:12中的代码。它没有评论,因为我放下了很快就问这里丢了我的头发!我担心的是,我希望我的char *目标为/cat.html?name=image但我只能获得/cat.html

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    const char *space = " ";
    const char *marker = "?";
    const char line[] = { "GET /cat.html?name=image HTTP/1.1" };
    int n = strlen(line), i, j, k, a;
    char string[n + 1];

    for (i = 0; i <= n; i++) {
        string[i] = line[i];
        string[n] = '\0';
    }
    printf(" line has %i characters \n\n", n);
    char *method = strtok(string, space);
    char *target = strtok(NULL, space);
    char *version = strtok(NULL, space);

    char *abs_path = strtok(target, marker);
    char *query = strtok(NULL, marker);

    printf("\n line is:%s \n"
           "\n method is:%s \n"
           "\n target is:%s \n"
           "\n version     is:%s \n"
           "\n abs_path is:%s \n"
           "\n query is:%s \n\n\n",
           line, method, target, version, abs_path, query);

    int l = strlen(target);
    if (strcmp(method, "GET") != 0) {
        printf("wrong method error 405 \n\n");
    }

    printf(" target contains %i characters \n\n", l);
    for (j = 0; j <= l; j++) {
        if (target[0] != '/') {
            printf("wrong target does not start with \\/error 501\n\n");
        }
        if (target[j] == '"') {
            printf("wrong target error 400 has a \" \n\n");
        }
    }
    if (strchr(abs_path, '.') == NULL) {
        printf("wrong absolute path has no \. \n\n");
    }
    if (strncmp(version, "HTTP/1.1", 8) != 0) {
        printf("wrong version not HTTP/1.1 error 505 \n\n");
    }
    return 0;
}

2 个答案:

答案 0 :(得分:3)

char * method = strtok(string, space);
char * target = strtok(NULL, space);
char * version = strtok(NULL, space);

在这些行之后,target 确实具有值"/cat.html?name=image"。问题是你再次在target上调用strtok,这将修改字符串:

abs_path = strtok(target, marker);

在该行之后,target将具有值"/cat.html"

如果您想保留target的原始值,则需要在第二个strtok之前复制它。在target

答案 1 :(得分:2)

strtok()修改传递给第一个参数的缓冲区。在前3次调用之后,methodtargetversion要么是NULL要么是string数组要对应于第一个,第二个和第三个的片段空间分隔部分。

char *method = strtok(string, space);
char *target = strtok(NULL, space);
char *version = strtok(NULL, space);

method指向"GET" string+0string[3]已设为'\0'
target"/cat.html?name=image" string+4string[24]设为'\0'version"HTTP/1.1"指向string+25

当您在strtok上发出对target的进一步来电时,string数组将被修改,?将被'\0'覆盖。< / p>

char *abs_path = strtok(target, marker);
char *query = strtok(NULL, marker);

abs_path指向"/cat.html" string+4string[13]设为'\0'
query"name=image"指向string+14

如果要保留target指向的字符串,则必须在第二组调用`strtok()之前复制:

char *saved_target = strdup(target);
char *abs_path = strtok(target, marker);
char *query = strtok(NULL, marker);

并在printf

中使用它
    printf("\n line is:%s \n"
           "\n method is:%s \n"
           "\n target is:%s \n"
           "\n version     is:%s \n"
           "\n abs_path is:%s \n"
           "\n query is:%s \n\n\n",
           line, method, saved_target, version, abs_path, query);