我正在阅读这本书,用C进行手工网络编程,在本章中,我正在阅读我们正在构建一个web客户端。这个web客户端的一个功能是解析传递给它的URL,以确定协议、主机名、文档路径等。解析功能的一部分如下:
void parse_url(char *url, char **hostname, char **port, char **path){
printf("URL: %s\n", url);
char *p;
p = strstr(url, "://");
char *protocol = 0;
if (p){
protocol = url;
printf("Protocol: %s\n", protocol);
*p = 0;
p += 3;
} else {
p = url;
}
printf("Protocol: %s\n", protocol);
if (protocol){
printf("Protocol: %s\n", protocol);
if (strcmp(protocol, "http")){
fprintf(stderr, "Unknown protocol, '%s'. Only 'http' is supported.\n",
protocol);
exit(1);
}
}每当我传入一个没有使用HTTP的URL,比如https://example.com (他们在书中使用的URL),我就会得到以下输出(我将额外的打印语句放在那里进行调试):
协议: https
协议: https
未知的协议'https‘。只支持'http‘。
我的问题是,指向URL的协议如何被截断到协议,而不是以前的整个URL?
发布于 2022-06-25 22:41:01
语句p = strstr(url, "://");将在url中查找"://"的第一次出现,并将"://"的第一个字节的地址存储在p中。因此,*p将评估为':'。如果没有找到"://",p将等于NULL。
如果找到"://",protocol将被设置为指向url的开头,然后'\0'被放置在p所指向的地址。因此,如果url以前包含"https://www.example.com\0",那么现在url包含"https\0//www.example.com\0" (包括末尾的'\0' )。
C中的字符串由'\0'终止。因此,任何处理字符串"https\0//www.example.com\0"的函数都将在'\0'第一次出现时停止处理该字符串。因此,printf("%s", protocol)将打印"https",strlen(p)将返回5,等等。
发布于 2022-06-25 22:36:17
作为用':'替换URL中的'\0'的替代方法。您可以获取相同的信息并使用指针数学计算URL的协议部分中有多少个字符,然后使用它只将那么多的字符放入另一个缓冲区。我们将该缓冲区初始化为零,以便在调用strncpy后字符串以null结尾。
这种方法对原始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("%s\n", 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
https://stackoverflow.com/questions/72757726
复制相似问题