我正在阅读这本书,《动手用C进行网络编程》,在我正在阅读的这一章中,我们正在构建一个web客户端。这个web客户端的功能之一是解析传递给它的URL,以确定协议、主机名、文档路径等。部分解析函数如下:
void parse_url(char *url, char **hostname, char **port, char **path){
printf("URL: %sn", url);
char *p;
p = strstr(url, "://");
char *protocol = 0;
if (p){
protocol = url;
printf("Protocol: %sn", protocol);
*p = 0;
p += 3;
} else {
p = url;
}
printf("Protocol: %sn", protocol);
if (protocol){
printf("Protocol: %sn", protocol);
if (strcmp(protocol, "http")){
fprintf(stderr, "Unknown protocol, '%s'. Only 'http' is supported.n",
protocol);
exit(1);
}
}
每当我传入一个不使用HTTP的URL时,例如https://example.com(他们在书中使用的URL),我得到以下输出(为了调试目的,我在那里添加了额外的print语句):
的URL: https://example.com
协议:https://example.com
https协议:
https协议:
未知协议,'https'。只支持'http'。
我的问题是,如何协议,这是指向URL,得到截断只有协议,而不是整个URL,因为它是以前?
语句p = strstr(url, "://");
将在url
中找到"://"
的第一个出现,并将"://"
的第一个字节的地址存储在p
中。所以*p
等于':'
。如果没有找到"://"
,则p
将等于NULL
。
如果找到"://"
,protocol
将被设置为指向url的开头,然后' '
将被放置在p
所指向的地址上。因此,如果url
之前包含"https://www.example.com "
,现在url
包含"https //www.example.com "
(包括最后的' '
)。
C中的字符串以' '
结束。因此,任何处理字符串"https //www.example.com "
的函数都会在第一次出现' '
时停止处理字符串。因此,printf("%s", protocol)
将打印"https"
,strlen(p)
将返回5,等等。
作为替代在URL中用' '
替换':'
。您可以获取相同的信息并使用指针数学来计算URL的协议部分中有多少字符,然后使用它来将这些字符仅strncpy
到另一个缓冲区中。我们将把该缓冲区初始化为0,以便在调用strncpy
后,字符串以空结束。
这种方法不会破坏原始URL字符串。
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
char *get_protocol(char *url);
int main() {
char url[] = "https://www.example.com";
char *protocol = get_protocol(url);
printf("%sn", protocol);
free(protocol);
return 0;
}
char *get_protocol(char *url) {
char *p = strstr(url, "://");
if (!p) return NULL;
size_t len = p - url;
char *result = calloc(len + 1, 1);
if (!result) return NULL;
strncpy(result, url, len);
return result;
}
结果:https