我想将字符串操作外包给函数,然后在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;
}
答案 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;
}