LibCurl undefined引用

时间:2017-12-15 15:13:24

标签: 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命令的末尾,但它对我不起作用。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

基于这一行:

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

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

首先,你需要纠正上面一行,因为它应该是

#include <curl/curl.h>

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

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

总而言之,如上所述修复了include行,编译代码的命令应如下所示:

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