C中的字符串被意外截断



我正在阅读这本书,《动手用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

最新更新