使用不带外部库的C查找HTML响应中的超链接



我需要在不使用外部库的情况下找出HTML响应中<a href="xxxxxx">形式的所有超链接。因此,我使用strtok(message, " n<>")将响应拆分为多个部分。如果最后一个片段是a,而当前片段以href开始,我们找到一个链接。但是,代码执行不好,导致内存问题。

VS代码不断弹出消息,文本如下:

无法打开"strlen.S":无法读取文件"/build/glibc-S7Ft5T/glibc-2.23/sysdeps/x86_64/strlen.S">

在终端中,它打印出:

[1]+完成"/usr/bin/gdb"--解释器=mi--tty=${DbgTerm}0<quot/tmp/Microsoft MIEngine In fjtfcdmp.4qw";1>quot/tmp/Microsoft MIEngine Out hlygokwk.gwa";

这是我的代码:

// Omit the sending and receiving part
//
if(recv(tcpSocket, response_buf, sizeof(response_buf), 0) < 0){
printf("Error with recv()n");
}
else {
printf("Successfully receive responsen");
// printf("Message received:n %sn", response_buf);
}
printf("===============================n");
char * const dupstr = strdup(response_buf);
char* token = NULL;
token =  strtok(dupstr, " n<>");
char last_token[2000];
char token_head[1000];
char a[] = "a";
char href[] = "href=";
while (token != 0) {
strcpy(last_token, token);
token = strtok(NULL, " n<>");
if(strcmp(last_token, a) == 0){
size_t len = strlen(token);
if(len>5){
strncpy(token_head, token, 5);
if(strcmp(token_head, href)== 0){
printf("%sn", token);
}
}
}
}

您在调试时尝试单步执行,并尝试逐步执行库函数。

在您发布的案例中,您尝试进入strlen()。通常,此类功能的源文件不包含在安装中。这就是调试器告诉找不到源文件的原因。

如果您正在用单步执行调试程序,请使用";下一个";跳过库函数的函数调用。

我看到的主要问题是您的代码没有正确检查strtok的返回值。您只在循环开始时检查token的值,但随后调用strtok。如果它返回NULL,那么直到循环的其余部分发生之后,您才会发现。

你想像这个一样把strtok移到循环的末尾

while (token != 0) {
if(strcmp(last_token, a) == 0){
size_t len = strlen(token);
if(len>5){
strncpy(token_head, token, 5);
if(strcmp(token_head, href)== 0){
printf("%sn", token);
}
}
}
strcpy(last_token, token);
token = strtok(NULL, " n<>");
}

这样检查实际上就完成了它应该做的事情。

或者,进行循环的另一种方法是使用for循环

for(token = strtok(dupstr, " n<>"); token != NULL; token = strtok(NULL, " n<>")) {
if(strcmp(last_token, a) == 0){
size_t len = strlen(token);
if(len>5){
strncpy(token_head, token, 5);
if(strcmp(token_head, href)== 0){
printf("%sn", token);
}
}
strcpy(last_token, token);
}

无论哪种方式,您都需要正确初始化last_token,因为在调用strcpy之前,它可能包含任何内容。

你也从来没有免费的dupstr。虽然这目前不是问题,因为它将在代码退出时处理,但无论何时分配内存,都要养成向free添加相应调用的好习惯。

最新更新