我使用 strtok() 编写了一个简单的 url 解析器。这是代码
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *protocol;
char *host;
int port;
char *path;
} aUrl;
void parse_url(char *url, aUrl *ret) {
printf("Parsing %s\n", url);
char *tmp = (char *)_strdup(url);
//char *protocol, *host, *port, *path;
int len = 0;
// protocol agora eh por exemplo http: ou https:
ret->protocol = (char *) strtok(tmp, "/");
len = strlen(ret->protocol) + 2;
ret->host = (char *) strtok(NULL, "/");
len += strlen(ret->host);
//printf("char at %d => %c", len, url[len]);
ret->path = (char *)_strdup(&url[len]);
ret->path = (char *) strtok(ret->path, "#");
ret->protocol = (char *) strtok(ret->protocol, ":");
// host agora é por exemplo address.com:8080
//tmp = (char *)_strdup(host);
//strtok(tmp, ":");
ret->host = (char *) strtok(ret->host, ":");
tmp = (char *) strtok(NULL, ":");
if(tmp == NULL) {
if(strcmp(ret->protocol, "http") == 0) {
ret->port = 80;
} else if(strcmp(ret->protocol, "https") == 0) {
ret->port = 443;
}
} else {
ret->port = atoi(tmp);
}
//host = (char *) strtok(NULL, "/");
}
/*
*
*/
int main(int argc, char** argv) {
printf("hello moto\n");
aUrl myUrl;
parse_url("http://teste.com/Teste/asdf#coisa", &myUrl);
printf("protocol is %s\nhost is %s\nport is %d\npath is %s\n", myUrl.protocol, myUrl.host, myUrl.port, myUrl.path);
return (EXIT_SUCCESS);
}
如您所见,我经常使用 strtok() 以便可以“切片”网址。我不需要支持不同于 http 或 https 的 url,所以它的完成方式解决了我的所有问题。我担心的是(这是在嵌入式设备上运行的) - 我在浪费内存吗?当我写类似的东西时
ret->protocol = (char *) strtok(tmp, "/");
然后稍后调用
ret->protocol = (char *) strtok(ret->protocol, ":");
我的第一个指针 ret->protocol 是否保留在内存中?我想也许我应该将第一次调用设置为 tmp 指针,调用 strtok 将 ret->protocol 指向字符串的右侧部分(第二次调用),然后再调用 free(tmp)。
使用 strtok 的最佳方法应该是什么?