【问题标题】:C program using getopt can't resolve url parameter使用getopt的C程序无法解析url参数
【发布时间】:2018-09-28 03:44:24
【问题描述】:

我正在尝试使用 getopt 从命令行输入一个 url,以用于 HTTP get、post、put 和 delete。 HTTP GET 早些时候工作,但由于某种原因,我无法弄清楚如何解析 url,以便 HTTP GET 现在成功。当我打印 url 时,它显示它是预期的格式,但 curl 抱怨说无法解析主机名。有人可以向我解释如何解决这个问题以及如何使它只有在命令行中输入的第一个 url 被接受?谢谢!

#include<stdio.h>
#include<getopt.h>
#include<curl/curl.h>
#include<stdlib.h>

#define OK 0
#define INIT_ERR 1
#define REQ_ERR 2

// function for HTTP GET
void get(char* url, CURL *curl, CURLcode res) {
    long http_code = 0;
    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            fprintf(stderr, "[CURL] Could not execute HTTP GET: %s\n", curl_easy_strerror(res));
            //return REQ_ERR;
        }
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
        printf("[HTTP CODE]: %ld\n", http_code);
        curl_easy_cleanup(curl);
    }
}

// function for HTTP PUT
void put() {

}

// function for HTTP POST
void post() {

}

// function for HTTP delete
void delete() {

}


int main(int argc, char **argv) {

    int c;
    char *content, *url; 
    CURL *curl;
    CURLcode res;

    while(1) {
        static struct option long_options[] = 
        {
            {"help", no_argument, 0, 'h'},
            {"get", no_argument, 0, 'g'},
            {"url ", required_argument, 0 , 'u'},
            {"post", required_argument, 0, 'o'},
            {"put", required_argument, 0, 'p'},
            {"delete", required_argument, 0, 'd'},
            {0,0,0,0}
        };

        // getopt stores option index here
        int long_index = 0;

        c = getopt_long_only(argc, argv, "hgo:p:d:u:", \
            long_options, &long_index);

        // detect end of options    
        if(c == -1)
            break;

        switch(c) {
            case 'h':
                printf("\n[HELP] Usage: ./test [VERB] 'content' [URL] <url>\n\n");
                printf("----------------------- HELP OPTIONS -----------------------------------------\n\n");
                printf(" FLAGS      ARGUMENTS   EXAMPLE ARG FORMAT      SUMMARY\n");
                printf("------------------------------------------------------------------------------\n");
                printf("-h/--help   N/A     N/A             help options\n");
                printf("-g/--get    N/A     N/A             [VERB] http get option\n");
                printf("-o/--post   'content'   'Post this stuff.'      [VERB] http post option\n");
                printf("-p/--put    'content'   'Put this stuff.'       [VERB] http put option\n");
                printf("-d/--delete 'content'   'Delete this stuff/'        [VERB] http delete option\n");
                printf("-u/--url    'url'       'http://www.cnn.com'        [URL] http url of server\n");
                printf("                'http://localhost:PORT' \n");
                printf("                'http://IPADDRESS:PORT'\n\n");
                printf("------------------------------------------------------------------------------\n");
                printf("            Example USAGE\n");
                printf("------------------------------------------------------------------------------\n");
                printf("HTTP GET -  ./test --get --url 'http://www.cnn.com\n");
                printf("HTTP POST - ./test --post 'Post this content.' --url 'http://localhost:8080\n");
                printf("HTTP PUT -  ./test --put 'Put this content.' --url 'http://localhost:8080\n");
                printf("HTTP DELETE -   ./test --delete 'Delete this content.' --url 'http://localhost:8080'\n\n");
                break;
            case 'g':
                printf("[HTTP GET]\n");
                url;
                get(url, curl, res);
                break;
            case 'u':
                url = optarg;
                printf("[HTTP URL] url: %s\n", url);
                break;
            case 'o':
                content = optarg;
                printf("[HTTP POST] content: %s\n", content);
                break;
            case 'p':
                content = optarg;
                printf("[HTTP PUT] content: %s\n", content);
                break;
            case 'd':
                content = optarg;
                printf("[HTTP DELETE] content: %s\n", content);
                break;
            case '?':
                //getopt_long already printed error message
                break;
            default:
                abort();
        }
    //get(url, curl, res);
    }

    return OK;
}

【问题讨论】:

  • 如果您只使用硬编码的 URL 字符串调用 get() 是否有效?如果是这样,那么人们只需要查看getopt 代码。如果没有,那么 getopt 的东西是不必要的混乱(对于你遇到的问题)。请注意,您传入了 rescurl*,但在函数中更新它们并不能帮助将它们从 get() 函数中取出,因为 C 按值传递参数。换句话说,这些论点对get() 毫无用处。
  • @MichaelBurr 是的,如果我在大小写“g”下对 url 字符串进行硬编码,则 HTTP GET 请求可以正常工作。
  • 你测试的命令行是什么?
  • @MichaelBurr ./test -g 适用于硬编码的网址。当我传递网址时,我使用 ./test -g --url 'localhost:8000'./test -g --url "localhost:8000"跨度>
  • 问题是你把-g选项放在--url选项之前所以get()在获取url之前被调用。试试:./test --url "whatever" -g

标签: c http curl libcurl getopt


【解决方案1】:

正如@MichaelBurr 指出的那样,根据此代码,-g 应该在 --url /-u 之后给出。我试过 ./test --url "hxxp://google.com" -g 并且正在工作。 您可能需要检查 localhost:8000

【讨论】:

  • 感谢您的回复,我最终也让它以这种方式工作。你能解释一下为什么会这样,或者我如何让它接受动词标志之后的 URL?
  • 如果是 'g':,您正在调用忽略其余参数的 get() 函数(在 get() 调用之后,将处理其余参数)。解决方案:在调用 get/post/put 之前处理所有传递的参数。
猜你喜欢
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多