【问题标题】:How to separate domain and path from URL in C?如何在C中将域和路径与URL分开?
【发布时间】:2020-04-04 15:50:57
【问题描述】:

我尝试从命令行参数读取一个 URL(可以包含或不包含路径,例如 http://google.comhttp://www.google.com/abc/dfg),然后将它们分成域名和路径,但结果似乎不正确,并且没有 valgrind没有显示错误,但 valgrind 显示错误。 我只是不知道如何解决它。有人可以帮忙吗?非常感谢!

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    char* domain;
    char* path;

    sscanf(argv[1], "http://%[^/]/%[^\n]", domain, path);
    printf("domain: %s\n", domain);
    printf("path: %s\n", path);
}

【问题讨论】:

  • scanf 不会为domainpath 分配存储空间。您必须传递有效的缓冲区。
  • 您可以使用strtok 将域与字符串中的路径分开。
  • 请注意https。您首先使用strstr 进行检查,结果为argv[1]
  • 那么我会在开始工作时 malloc 吗?但是我不知道域和路径是多长时间?

标签: html c regex http


【解决方案1】:

valgrind 显示错误

这是正确的做法,您错过了将 domainpath 初始化为有效(足够)存储

例如做

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    char domain[32];
    char path[64];

    sscanf(argv[1], "http://%31[^/]/%63[^\n]", domain, path);
    printf("domain: %s\n", domain);
    printf("path: %s\n", path);
}

请注意,我将读取的长度限制为不写出数组(我删除了大小中的 1 以便为空字符留出位置)

但我也鼓励您检查 argvsscanf 返回的值,以了解您读取了多少元素,并返回一个值:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    char domain[32];
    char path[64];

    if (argc < 2) {
      fprintf(stderr, "Usage: %s <URL>\n", *argv);
      return -1;
    }

    switch (sscanf(argv[1], "http://%31[^/]/%63[^\n]", domain, path)) {
    case 2:
      printf("path: %s\n", path);
      /* no break */
    case 1:
      printf("domain: %s\n", domain);
      break;
    default:
      fputs("this is not a valid url\n", stderr);
    }

    return 0;
}

当然你也可以将domain[0]path[0]初始化为0。

编译和执行:

pi@raspberrypi:/tmp $ gcc -Wall a.c
pi@raspberrypi:/tmp $ ./a.out
Usage: ./a.out <URL>
pi@raspberrypi:/tmp $ ./a.out aze
this is not a valid url
pi@raspberrypi:/tmp $ ./a.out http://google.com
domain: google.com
pi@raspberrypi:/tmp $ ./a.out http://google.com/abc/dfg
path: abc/dfg
domain: google.com
pi@raspberrypi:/tmp $ ./a.out http://google.com/a_too_long_path_to_be_memorized_in_only_64_characters_so_it_is_cut
path: a_too_long_path_to_be_memorized_in_only_64_characters_so_it_is_
domain: google.com
pi@raspberrypi:/tmp $ 

请注意,安全 url (https) 被视为无效

【讨论】:

  • 我试过你的代码,但我的编译结果仍然显示错误。 ==24992== 条件跳转或移动取决于未初始化的值 ==24992== 在 0x48B9B1A: __vfscanf_internal (vfscanf-internal.c:2471) ==24992== 在 0x48B4471: __isoc99_sscanf (isoc99_sscanf.c:31) ==24992== by 0x1091A2: main (a.c:9) ==24992== 未初始化的值是由堆栈分配创建的 ==24992== 在 0x109169: main (a.c:5)
  • @Emmm 你确定你复制对了吗?我做了一些编辑,刷新页面,然后再做一次。当然在答案中使用第二个建议
  • 对不起..我犯了一个错误。现在可以了。非常感谢!
  • 如果我需要使用指针而不是数组来存储域和路径,我该如何修改代码?既然不知道sscanf之前要malloc多少内存?
  • @Emmm 定义域和路径不能长于 argv[1],因此您可以为两者分配 strlen(argv[1]) 字符
猜你喜欢
  • 1970-01-01
  • 2014-01-18
  • 2018-07-01
  • 2013-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 2011-12-11
相关资源
最近更新 更多