外包strtok()在c中的功能

时间:2016-11-17 15:53:40

标签: c

我想将字符串操作外包给函数,然后在main中查询结果。这不起作用,我不明白为什么。

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

void splitRequest(char request[], char method[], char ressource[], char proto[]) {

    method = strtok(request, " ");
    ressource = strtok(NULL, " ");
    proto = strtok(NULL, " ");
    printf("\nResult:\n\nmethod:\t\t%s\nressource:\t%s\nproto:\t\t%s\n",method,ressource,proto);
}

int main()
{    
    char method[50], ressource[50], proto[50], request[50];
    memset(method, '\0', 50);
    memset(ressource, '\0', 50);
    memset(proto, '\0', 50);
    memset(request, '\0', 50);
    strcpy(request,"Get /index.htm HTTP/1.1");

    //rehash query
    splitRequest(request, method, ressource, proto);

    //check Results
    printf("\nResult:\n\nmethod:\t\t%s\nressource:\t%s\nproto:\t\t%s\n",method,ressource,proto);

    return 0;
}

2 个答案:

答案 0 :(得分:3)

splitRequest函数中,所有参数都是指针。更重要的是,它们是局部变量。所以对它们的所有更改(比如让它们指向其他地方)只会影响局部变量,而不会影响其他任何内容。

解决方案是复制到内存。也许像是

char *temp;

if ((temp = strtok(request, " ")) != NULL)
{
    strcpy(method, temp);
}

// And so on...

对我的意思进行一点阐述......

在C中,所有函数参数都按值传递。这意味着它们的值是复制,并且该函数只有该值的本地副本。查阅副本当然不会改变原始值。

指针也一样。当您调用splitRequest函数时,会复制您传递的指针。在函数内部,变量method(例如)指向您在main函数中定义的数组的内存。分配给此变量时,就像使用

一样
method = strtok(...);

你只修改局部变量,指针的本地副本。当函数返回时,局部变量method超出范围,并且对它的所有更改都将丢失。

这个问题有两个解决方案。一种是通过引用来模拟传递(C不具备的东西,这就是为什么它必须被模拟),但只要你有一个数组就行不通。因此,第二个也是最简单的解决方案:复制到本地变量method指向的内存,这就是我在上面显示的内容。

一个重要的注意事项:当你调用splitRequest函数,传递数组时,数组本身不会被传递。相反,数组衰减指向其第一个元素的指针,而在函数内部,由参数定义的变量是指针而不是数组。

电话

splitRequest(request, method, ressource, proto);

等于

splitRequest(&request[0], &method[0], &ressource[0], &proto[0]);

功能声明

void splitRequest(char request[], char method[], char ressource[], char proto[])

等于

void splitRequest(char *request, char *method, char *ressource, char *proto)

所以没有字符串不被复制,只有指针。否则,在分配指针时会出现错误,因为您无法分配给数组,只能复制到它们。

答案 1 :(得分:0)

发现另一种解决方法更有效:

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

void splitRequest(char request[], char **method, char **ressource, char **proto) {

    *method = strtok(request, " ");
    *ressource = strtok(NULL, " ");
    *proto = strtok(NULL, " ");
    printf("\nResult:\n\nmethod:\t\t%s\nressource:\t%s\nproto:\t\t%s\n",*method,*ressource,*proto);
}

int main()
{    
    char *method, *ressource, *proto, request[50];
    memset(request, '\0', 50);
    strcpy(request,"Get /index.htm HTTP/1.1");

    //rehash query
    splitRequest(&request, &method, &ressource, &proto);

    //check Results
    printf("\nResult:\n\nmethod:\t\t%s\nressource:\t%s\nproto:\t\t%s\n",method,ressource,proto);

    return 0;
}