c - LibCurl undefined reference

标签 c gcc google-api libcurl google-translate

尝试使用 Libcurl 用 C 编写翻译程序。文本编辑器是 Atom 并使用 gnu 编译器。

当编译为“gcc example.c”时,我收到以下错误:

Navid@LAPTOP-ASS7BGNB /c/users/navid/desktop/Lipcurl/libcurl-sample-master/curl
$ gcc projektzwei.c
C:\Users\Navid\AppData\Local\Temp\ccwZwaAr.o:projektzwei.c:(.text+0xa18): undefined reference to `_imp__curl_easy_init'
C:\Users\Navid\AppData\Local\Temp\ccwZwaAr.o:projektzwei.c:(.text+0xa4a): undefined reference to `_imp__curl_easy_setopt'
C:\Users\Navid\AppData\Local\Temp\ccwZwaAr.o:projektzwei.c:(.text+0xa83): undefined reference to `_imp__curl_easy_setopt'
C:\Users\Navid\AppData\Local\Temp\ccwZwaAr.o:projektzwei.c:(.text+0xa90): undefined reference to `_imp__curl_easy_perform'
C:\Users\Navid\AppData\Local\Temp\ccwZwaAr.o:projektzwei.c:(.text+0xaa6): undefined reference to `_imp__curl_easy_strerror'
C:\Users\Navid\AppData\Local\Temp\ccwZwaAr.o:projektzwei.c:(.text+0xacf): undefined reference to `_imp__curl_easy_cleanup'
collect2.exe: error: ld returned 1 exit status

当编译为“gcc projektzwei.c -lcurl”时,我收到此错误:

Navid@LAPTOP-ASS7BGNB /c/users/navid/desktop/Lipcurl/libcurl-sample-master/curl
$ gcc projektzwei.c -lcurl
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lcurl
collect2.exe: error: ld returned 1 exit status

这是我的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "stdafx.h"
#include "libcurl/include/curl/curl.h"

#ifdef _DEBUG
#pragma comment(lib, "libcurl/lib/libcurl_a_debug.lib")
#else
#pragma comment(lib, "libcurl/lib/libcurl_a.lib")
#endif


#define TEXT_MAX 2000
#define CANDIDAT_INPUT 2        /*Amount of valid inputs for candidat*/
#define PARTY_INPUT 14          /*Amount of valid inputs for parties*/

void prepare_files(char *Key);
void Introduction(int Sprog);
void Assemble_URL_To_Translate(int Sprog, FILE *fp);
char *create_URL(char Key[], char Source[], char Target[], char Message[]);
const char *chosen_language(int Target);
int valid_input_checker(const char **index, int array_lenght, char input[]);
void create_message(FILE *fp, char *Message);
void fil_print(FILE *fp);
void Partier(char input[], int Sprog, char chosen_party[]);
const char *chosen_party(char parti_input[]);
void Candidat_Exist(char parti_input[], int Sprog, char chosen_party[]);
char *delete_space(char text[]);
void match_and_insert(int(*str_pred)(char*), char str[], int str_in_len, const char *prefix, char str_out[], int str_out_len);
int space_detector(char* cp);
void translator(void);

int main(void)
{
    int Sprog;

    /*User is asked to choose language*/

    printf("Choose language:\n"
        "(1) Dansk\n(2) English\n(3) Turk\n(4) Polski\n(5) Alearabia"
        "\n(6) Deutsch\n(7) Kurdi\n(8) Romanesc\n(9) Bosanski\n(10) Soomaali\n");
    scanf("%d", &Sprog);
    Introduction(Sprog);    /*Initializes the program with the given language*/

    return 0;
}
void prepare_files(char *Key)
{
    FILE *fp;

    fp = fopen("API.txt", "r");
    if (fp == NULL)
    {
        printf("Filen kunne ikke �bnes.\n");
        exit(EXIT_FAILURE);
    }
    while (!feof(fp))
    {
        fscanf(fp, "%s", Key);
    }
}
void Assemble_URL_To_Translate(int Sprog, FILE *fp)
{
    /*laver api key, target, message og url*/
    char SOURCE[5] = "da";
    char TARGET[5];
    char MESSAGE[TEXT_MAX];
    char KEY[100];
    char URL[TEXT_MAX];
    URL[0] = '\0';

    prepare_files(KEY);
    strcpy(TARGET, chosen_language(Sprog));

    create_message(fp, MESSAGE);
    fp = fopen("Translate_Input.txt", "w");
    strcat(URL, create_URL(KEY, SOURCE, TARGET, MESSAGE));
    fprintf(fp, "%s", URL);
    fil_print(fp);
}
void Introduction(int Sprog)
{
    /*Function to print introduction at the chosen language and ask the user what their next move is.*/
    FILE *fp;
    char parti_input[5];    /*Array for user input*/
    const char *valid_inputs[PARTY_INPUT] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "b" }; /*All the valid input options in the scanf*/
    char party[50]; /*Array to store the string containing what party has been chosen*/

    /*This will be replaced when we got a translator function.*/
    fp = fopen("Introduktion.txt", "r");
    Assemble_URL_To_Translate(Sprog, fp);
    translator();

    do           /*Asks the user to tell us what party they want to have a look at or optionally, go back.*/
    {
        printf("Press:\n"
            "(1) Alternativet\n(2) Det Konversative Folkeparti\n(3) DF\n(4) Enhedslisten\n"
            "(5) Fjordlisten\n(6) Kristendemokraterne\n(7) Liberal Alliance\n(8) Nationalpartiet\n"
            "(9) Nye Borgerlige\n(10) Radikale Venstre\n(11) SF\n(12) Socialdemokraterne\n(13) Venstre\n"
            "(b) for at gaa tilbage\n");
        scanf("%s", &parti_input);
    }
    while (valid_input_checker(valid_inputs, PARTY_INPUT, parti_input) == 0);

    if (strchr(parti_input, 'b') != NULL)
    {
        main();
    }
    else
    {
        strcpy(party, chosen_party(parti_input));
        Partier(parti_input, Sprog, party);
    }
}
char *create_URL(char Key[], char Source[], char Target[], char Message[])
{
    char URL[TEXT_MAX] = "https://www.googleapis.com/language/translate/v2?key=&source=&target=&q=";
    char *URLptr = URL;
    sprintf(URL, "https://www.googleapis.com/language/translate/v2?key=%s&source=%s&target=%s&q=", Key, Source, Target);

    Message = delete_space(Message);

    strcat(URL, Message);

    return URLptr;
}
const char *chosen_language(int Target)
{
    /*Finds out what party has been chosen and returns it as a string.*/
    const char *sprog[] = { "da", "en", "tr", "pl", "ar", "de", "ku", "ro", "bs", "so" };

    return sprog[Target - 1];   /*-1 cause array index starts at 0, but the users lowest valid input is 1*/
}
const char *chosen_party(char parti_input[])
{
    /*Finds out what party has been chosen and returns it as a string.*/
    int input_tal = atoi(parti_input);

    const char *partier[] = { "Alternativet", "Det_Konversative_Folkeparti", "DF", "Enhedslisten"
        ,"Fjordlisten", "Kristendemokraterne", "Liberal_Alliance", "Nationalpartiet"
        ,"Nye_Borgerlige", "Radikale_Venstre", "SF", "Socialdemokraterne", "Venstre" };

    return partier[input_tal - 1];  /*-1 cause array index starts at 0, but the users lowest valid input is 1*/
}
int valid_input_checker(const char **index, int array_lenght, char input[])
{
    /*Algoritme to find out if the entered input from the user is valid.*/
    for (int i = 0; i < array_lenght; i++)
    {
        if (strcmp(index[i], input) == 0)   /*If we find a match, we return 1*/
        {
            return 1;
        }
        else if (i == array_lenght && (strcmp(index[i], input) != 0))   /*If we have been through the entire index og valid input without a match, we return 0*/
        {
            return 0;
        }
    }
    return 0;
}
void create_message(FILE *fp, char *Message)
{
    int ch;
    int i = 0;

    while ((ch = fgetc(fp)) != EOF)
    {
        Message[i] = ch;
        i++;
    }
    Message[i] = '\0';

    fclose(fp); /*As soon as we are done with the file we close it. ALWAYS do this.*/
}
void fil_print(FILE *fp)
{
    /*Simple algoritme to print a file.*/
    int ch;
    int i = 0;
    char str[400];  /*Array where the file is getting stored*/

    while ((ch = fgetc(fp)) != EOF)
    {
        str[i] = ch;
        i++;
    }
    str[i] = '\0';
    //printf("%s\n", str);  /*Prints the file*/

    fclose(fp); /*As soon as we are done with the file we close it. ALWAYS do this.*/
}
void Partier(char parti_input[], int Sprog, char chosen_party[])
{
    /*Function to print the overview of what the chosen party stands for and gives the user the option to view the candidats or go back.*/
    FILE *fp;
    char kandidat_input[5];                 /*This is the input we get from the user, which tells us whether they user wants to look at candidats for the party, og go back.*/
    const char *valid_inputs[CANDIDAT_INPUT] = { "1", "b" };    /*Array of valid inputs for the scanf*/

    char party_intro[50];   /*Array to store the path for the party overview file.*/
    sprintf(party_intro, "Partier/%s/M�rkesager.txt", chosen_party);    /*Stores the path*/
    printf("party: %s\n", party_intro); /*Nice to have, not necessary. Tells you what path it is going to print from.*/

    fp = fopen(party_intro, "r");   /*Opens the file at the given path*/
    fil_print(fp);  /*Prints the file*/

    do/*User is asked to tell what their next move is*/
    {
        printf("tryk:\n"
            "(1) Se partiets kandidater\n");
        printf("(b) for at gaa tilbage\n");
        scanf("%s", &kandidat_input);
    }
    while (valid_input_checker(valid_inputs, CANDIDAT_INPUT, kandidat_input) == 0); /*We have a function 'valid_input_checker' which returns either 1 or 0. If 1,
                                                                                    the users input was valid and the program will proceed. If 0, the input was incorrect
                                                                                    and the user is asked again to type something.*/
    if (strchr(kandidat_input, 'b') != NULL)        /*Checks if the input was 'b'*/
    {
        Introduction(Sprog);
    }
    else
        Candidat_Exist(parti_input, Sprog, chosen_party);
}
void Candidat_Exist(char parti_input[], int Sprog, char chosen_party[])
{
    /*Prints every single candidat for the given party.*/
    FILE *fp;
    char user_input[5];
    char candidattxt[50];   /*Array to later store the string used to open the candidat text file in fopen.*/
    char path[40];          /*Array to tell your computer where it is going to find the text file.*/
    sprintf(path, "Partier/%s/Kandidat_\0", chosen_party);  /*Takes the users chosen party and adds it to the path, to determine where we are going to find the text files.*/

    int size = 2;

    /*Algoritme to check if the next candidat exist and will print it if it does. If it exist, the 'size' is incremented by 1, so we keep cycling through the list of
    candidats. If it doesn't, we break.*/
    for (int i = 1; i < size; i++)
    {
        sprintf(candidattxt, "%s%d.txt", path, i);      /*All candidates are saved as "Kandidat_X" where X is an integer starting at 1. We finish the path by specifying what
                                                        file want to check.*/
        fp = fopen(candidattxt, "r");                   /*Opens the candidats text file*/
        if (fp != NULL)                                 /*Checks if the file exist*/
        {
            /*printf("candi: %s\n", candidattxt);       Command to show you what candidat is getting printet*/
            fil_print(fp);
            fclose(fp);
            size++;
        }
        else if (fp == NULL)
        {
            break;
        }
    }
    do/*User is asked to tell what their next move is*/
    {
        printf("tryk:\n(b) for at gaa tilbage\n");
        scanf("%s", &user_input);
    }
    while (strcmp(user_input, "b") != 0);   /*We have a function 'valid_input_checker' which returns either 1 or 0. If 1,
                                                                                    the users input was valid and the program will proceed. If 0, the input was incorrect
                                                                                    and the user is asked again to type something.*/
    Partier(parti_input, Sprog, chosen_party);
}
char *delete_space(char text[])
{
    char str_res[TEXT_MAX];
    char *str_res_ptr = str_res;
    int i, j, k;

    /* Initialize str_res til zero */
    for (i = 0; i < TEXT_MAX; ++i)
        str_res[i] = '\0';
    printf("len: %d\n", strlen(text));
    match_and_insert(space_detector, text, 200, "%20", str_res, TEXT_MAX);

    for (j = 0, k = 0; j < 200; j++)
    {
        str_res[j - k] = str_res[j];
        if (str_res[j] == ' ')
            k++;
    }
    str_res[j] = '\0';

    return str_res_ptr;
}
void match_and_insert(int(*str_pred)(char*), char str[], int str_in_len, const char *prefix, char str_out[], int str_out_len)
/*Shoutout til Kurt N�rmark*/
{
    int i = 0, o = 0;

    while (i < str_in_len)
    {
        int match_result = str_pred(str + i);
        if (match_result > 0)
        {
            strcpy(str_out + o, prefix);
            o += strlen(prefix);
            strncpy(str_out + o, str + i, match_result);
            i += match_result; o += match_result;
        }
        else if (match_result == 0)
        {
            str_out[o++] = str[i++];
        }
        else
        {
            printf("Should not happen!\n");
            exit(EXIT_FAILURE);
        }
    }
}
int space_detector(char* cp)
{
    int result = isspace(cp[0]);
    if (result)
        return 1;
    else
        return 0;
}

void translator(void)
{
    CURL *curl;
    CURLcode res;

    int ch, i = 0;
    char Message[2000];
    FILE *fp2;

    fp2 = fopen("Translate_Input.txt", "r");

    while ((ch = fgetc(fp2)) != EOF)
    {
        Message[i] = ch;
        i++;
    }

    Message[i] = '\0';

    curl = curl_easy_init();

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, Message);

        FILE *fp = fopen("target.txt", "w");

        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

        /* Perform the request, res will get the return code */
        res = curl_easy_perform(curl);

        /* Check for errors */
        if (res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                curl_easy_strerror(res));


        /* always cleanup */
        curl_easy_cleanup(curl);

        fclose(fp);
    }
}

我搜索了一下,似乎大多数人都通过添加来修复它 -lcurl 在 gcc 命令末尾,但它对我不起作用。有什么想法吗?

最佳答案

基于这一行:

#include "libcurl/include/curl/curl.h"

看起来你还没有在你的机器上安装curl,你刚刚下载了源代码并编译了它。这并不是错误的做法,但它确实会让你的生活变得更加困难。

首先您需要更正上面的行

#include <curl/curl.h>

然后,您需要通过添加“-Ilibcurl/include”来告诉编译器包含文件的位置。通过这样做,这意味着如果/当您正确安装 libcurl 时,您不需要对代码进行任何更改 - 您只需删除 -I 选项即可。

其次,您还需要使用 -L 选项告诉编译器(技术上是链接器)库的位置。看起来应该是“-Llibcurl/lib/”

总而言之,按照上面修复了包含行后,编译代码的命令应如下所示:

gcc -Ilibcurl/include -Llibcurl/lib projektzwei.c -lcurl

关于c - LibCurl undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47835094/

相关文章:

c - 将 Objective C 中的多数组传递给函数

将 uint8 转换为 uint32

c - 根据位置每 3 个元素从数组中删除元素

c - pthreads、setjmp、longjmp。你怎么知道一个函数何时结束运行?

gcc - 如何使用 ARM 的 OpenMAX 开发层 (DL) 进行构建和解码

gcc - 英特尔编译器/LLVM 上的并行位存储/并行位提取?

c - NOP 字符 0x90 的 printf 在 x86_64 和 i686 上编译时不同

javascript - 带有图例和其他颜色的 Google Charts API 散点图

c# - 下载所有 Google 表格

javascript - Google map Javascript API/街景 FOV