Thread: working with multiple source files

  1. #1
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242

    working with multiple source files

    Hi all.

    This is my first time that I'm trying to use multiple source files. Firstly, here is my full code that compiles and works fine. Sorry for the large program. I was able to work with multiple source files for simple programs, but need help with this particular program.

    Code:
    // getlinks: get URLs from a forum
    
    #include <curl/curl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define URL_LENGTH 150
    
    struct MemoryStruct {
        char *memory;
        size_t size;
    };
    
    static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
    char ** GetLinks(struct MemoryStruct datastruct);
    struct MemoryStruct GetInMemory(char *url);
    
    int main(void)
    {
        curl_global_init(CURL_GLOBAL_ALL);
    
        struct MemoryStruct data;
        char *forum_url = "http://cboard.cprogramming.com/c-programming/";
    
        data = GetInMemory(forum_url);
        GetLinks(data);
        free(data.memory);
        return 0;
    }
    
    // Get webpage into memory
    struct MemoryStruct GetInMemory(char *url)
    {
        CURL *myhandle;
        CURLcode result;
        struct MemoryStruct datastruct;
        char *URL;
    
        URL = url;
        datastruct.memory = malloc(1); // will be grown as needed by realloc
        datastruct.size = 0; // no data at this point
        if((myhandle = curl_easy_init()) == NULL)
        {
            perror("curl_easy-init error");
            exit(EXIT_FAILURE);
        }
        if((result = curl_easy_setopt(myhandle, CURLOPT_URL, URL)) != CURLE_OK)
        {
            perror("CURLOP_URL error");
            exit(EXIT_FAILURE);
        }
        if((result = curl_easy_setopt(myhandle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback)) != CURLE_OK)
        {
            perror("CURLOPT_WRITEFUNCTION error");
            exit(EXIT_FAILURE);
        }
        if((result =  curl_easy_setopt(myhandle, CURLOPT_WRITEDATA, &datastruct)) != CURLE_OK)
        {
            perror("CURLOPT_WRITEDATA error");
            exit(EXIT_FAILURE);
        }
        if((result = curl_easy_perform(myhandle)) != 0)
        {
            perror("curl_easy_perform error");
            exit(EXIT_FAILURE);
        }
        curl_easy_cleanup(myhandle);
        return datastruct;
    }
    
    static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
    {
        size_t realsize = size * nmemb;
        struct MemoryStruct *mem = (struct MemoryStruct *)userp;
    
        mem->memory = realloc(mem->memory, mem->size + realsize + 1);
        if (mem->memory == NULL) /* out of memory! */
        {
            printf("not enough memory (realloc returned NULL)\n");
            exit(EXIT_FAILURE);
        }
        memcpy(&(mem->memory[mem->size]), contents, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
        return realsize;
    }
    
    char ** GetLinks(struct MemoryStruct datastruct)
    {
        char * temp_string;
        char * memory_copy;
        char * match; // pointer to search match;
        int location; // location of search match;
        static char * links[100];
        char *search_string = "http://cboard.cprogramming.com/c-programming/";
        int ch; // test character
        int array_ctr = 0, len_memory_string, len_temp_string, url_buffer_ctr = 0;
    
        len_memory_string = strlen(datastruct.memory);
        if((memory_copy = malloc(len_memory_string * sizeof(char) + 1)) == NULL)
        {
            perror("Memory allocation  error #1");
            exit(EXIT_FAILURE);
        }
        strcpy(memory_copy, datastruct.memory);
        while((match = strstr(memory_copy, search_string)) != NULL)
        {
            location = match - memory_copy;
            if((links[array_ctr] = malloc(URL_LENGTH * sizeof(char))) == NULL) // allocate memory for pointer to hold URL
            {
                perror("Memory allocation error #2");
                exit(EXIT_FAILURE);
            }
            while((ch = memory_copy[location]) != '"' && (ch = memory_copy[location]) != '?')
            {
                links[array_ctr][url_buffer_ctr] = ch;
                location++;
                url_buffer_ctr++;
            }
            if((ch = memory_copy[location]) == '"')
            {
                links[array_ctr][url_buffer_ctr] = '\0';
                puts(links[array_ctr]);
                array_ctr++; // increment array to accept new URL
                url_buffer_ctr = 0; // reset
                location++; // move past "
                len_temp_string = strlen(memory_copy) - location; // the rest of memory_copy after the "
                if((temp_string = malloc(len_temp_string * sizeof(char) + 1)) == NULL)
                {
                    perror("Memory allocation error #3");
                    exit(EXIT_FAILURE);
                }
                strcpy(temp_string, &memory_copy[location]);
                if((memory_copy = realloc(memory_copy, len_temp_string + 1)) == NULL)
                {
                    perror("Memory allocation error #4");
                    exit(EXIT_FAILURE);
                }
                strcpy(memory_copy, temp_string);
                continue;
            }
            if((ch = memory_copy[location]) == '?')
            {
                url_buffer_ctr = 0; // reset
                location++; // move past ?
                len_temp_string = strlen(memory_copy) - location;
                if((temp_string = realloc(temp_string, len_temp_string + 1)) == NULL)
                {
                    perror("Memory allocation error #5");
                    exit(EXIT_FAILURE);
                }
                strcpy(temp_string, &memory_copy[location]);
                if((memory_copy = realloc(memory_copy, len_temp_string +1)) == NULL)
                {
                    perror("Memory allocation error #6");
                    exit(EXIT_FAILURE);
                }
                strcpy(memory_copy, temp_string);
                continue;
            }
        }
        free(memory_copy);
        free(temp_string);
        return links;
    }
    I want to put the functions into a separate file, so that I can use them in another program. But I also want to test this program by breaking it down into separate files and building it from the files.

    Anyway, here are the 3 files that I have broken the program down into.

    main.c
    Code:
    // getlinks: get URLs from a forum
    
    #include <curl/curl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "links.h"
    
    #define URL_LENGTH 150
    
    static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
    char ** GetLinks(struct MemoryStruct datastruct);
    struct MemoryStruct GetInMemory(char *url);
    
    int main(void)
    {
        curl_global_init(CURL_GLOBAL_ALL);
    
        struct MemoryStruct data;
        char *forum_url = "http://cboard.cprogramming.com/c-programming/";
    
        data = GetInMemory(forum_url);
        GetLinks(data);
        free(data.memory);
        return 0;
    }
    links.c
    Code:
    /* module containing link functions */
    
    #include "links.h"
    #include <curl/curl.h>
    #include <stdio.h>
    
    struct MemoryStruct {
        char *memory;
        size_t size;
    };
    
    static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
    // Get webpage into memory
    struct MemoryStruct GetInMemory(char *url)
    {
        CURL *myhandle;
        CURLcode result;
        struct MemoryStruct datastruct;
        char *URL;
    
        URL = url;
        datastruct.memory = malloc(1); // will be grown as needed by realloc
        datastruct.size = 0; // no data at this point
        if((myhandle = curl_easy_init()) == NULL)
        {
            perror("curl_easy-init error");
            exit(EXIT_FAILURE);
        }
        if((result = curl_easy_setopt(myhandle, CURLOPT_URL, URL)) != CURLE_OK)
        {
            perror("CURLOP_URL error");
            exit(EXIT_FAILURE);
        }
        if((result = curl_easy_setopt(myhandle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback)) != CURLE_OK)
        {
            perror("CURLOPT_WRITEFUNCTION error");
            exit(EXIT_FAILURE);
        }
        if((result =  curl_easy_setopt(myhandle, CURLOPT_WRITEDATA, &datastruct)) != CURLE_OK)
        {
            perror("CURLOPT_WRITEDATA error");
            exit(EXIT_FAILURE);
        }
        if((result = curl_easy_perform(myhandle)) != 0)
        {
            perror("curl_easy_perform error");
            exit(EXIT_FAILURE);
        }
        curl_easy_cleanup(myhandle);
        return datastruct;
    }
    
    static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
    {
        size_t realsize = size * nmemb;
        struct MemoryStruct *mem = (struct MemoryStruct *)userp;
    
        mem->memory = realloc(mem->memory, mem->size + realsize + 1);
        if (mem->memory == NULL) /* out of memory! */
        {
            printf("not enough memory (realloc returned NULL)\n");
            exit(EXIT_FAILURE);
        }
        memcpy(&(mem->memory[mem->size]), contents, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
        return realsize;
    }
    
    // Get links from webpage
    char ** GetLinks(struct MemoryStruct datastruct)
    {
        char * temp_string;
        char * memory_copy;
        char * match; // pointer to search match;
        int location; // location of search match;
        static char * links[100];
        char *search_string = "http://cboard.cprogramming.com/c-programming/";
        int ch; // test character
        int array_ctr = 0, len_memory_string, len_temp_string, url_buffer_ctr = 0;
    
        len_memory_string = strlen(datastruct.memory);
        if((memory_copy = malloc(len_memory_string * sizeof(char) + 1)) == NULL)
        {
            perror("Memory allocation  error #1");
            exit(EXIT_FAILURE);
        }
        strcpy(memory_copy, datastruct.memory);
        while((match = strstr(memory_copy, search_string)) != NULL)
        {
            location = match - memory_copy;
            if((links[array_ctr] = malloc(URL_LENGTH * sizeof(char))) == NULL) // allocate memory for pointer to hold URL
            {
                perror("Memory allocation error #2");
                exit(EXIT_FAILURE);
            }
            while((ch = memory_copy[location]) != '"' && (ch = memory_copy[location]) != '?')
            {
                links[array_ctr][url_buffer_ctr] = ch;
                location++;
                url_buffer_ctr++;
            }
            if((ch = memory_copy[location]) == '"')
            {
                links[array_ctr][url_buffer_ctr] = '\0';
                puts(links[array_ctr]);
                array_ctr++; // increment array to accept new URL
                url_buffer_ctr = 0; // reset
                location++; // move past "
                len_temp_string = strlen(memory_copy) - location; // the rest of memory_copy after the "
                if((temp_string = malloc(len_temp_string * sizeof(char) + 1)) == NULL)
                {
                    perror("Memory allocation error #3");
                    exit(EXIT_FAILURE);
                }
                strcpy(temp_string, &memory_copy[location]);
                if((memory_copy = realloc(memory_copy, len_temp_string + 1)) == NULL)
                {
                    perror("Memory allocation error #4");
                    exit(EXIT_FAILURE);
                }
                strcpy(memory_copy, temp_string);
                continue;
            }
            if((ch = memory_copy[location]) == '?')
            {
                url_buffer_ctr = 0; // reset
                location++; // move past ?
                len_temp_string = strlen(memory_copy) - location;
                if((temp_string = realloc(temp_string, len_temp_string + 1)) == NULL)
                {
                    perror("Memory allocation error #5");
                    exit(EXIT_FAILURE);
                }
                strcpy(temp_string, &memory_copy[location]);
                if((memory_copy = realloc(memory_copy, len_temp_string +1)) == NULL)
                {
                    perror("Memory allocation error #6");
                    exit(EXIT_FAILURE);
                }
                strcpy(memory_copy, temp_string);
                continue;
            }
        }
        free(memory_copy);
        free(temp_string);
        return links;
    }
    links.h
    Code:
    /* links.h: header file for links.c */
    
    #include <stdio.h>
    
    #ifndef _LINKS_H_
    #define _LINKS_H_
    
    static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
    char ** GetLinks(struct MemoryStruct datastruct);
    struct MemoryStruct GetInMemory(char *url);
    
    #endif // _LINKS_H_
    Now when I try to build the program, I get the below error messages, but don't know how to fix them. There were a few more errors before, but I just played around to reduce them. But I don't really know what I am doing.

    Thanks in advance.

    Code:
    links.h|9|warning: 'struct MemoryStruct' declared inside parameter list [enabled by default]|
    links.h|9|warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]|
    links.c|71|error: conflicting types for 'GetLinks'|
    links.h|9|note: previous declaration of 'GetLinks' was here|
    links.c||In function 'GetLinks':|
    links.c|92|error: 'URL_LENGTH' undeclared (first use in this function)|
    links.c|92|note: each undeclared identifier is reported only once for each function it appears in|
    ||=== Build finished: 2 errors, 2 warnings (0 minutes, 0 seconds) ===|
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Every file that uses a name must have a declaration for that name, either directly or by including a header. Your errors and warnings can be fixed by moving structure definitions and macros to the links.h header.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Working with multiple source file
    By ncode in forum C++ Programming
    Replies: 11
    Last Post: 03-30-2012, 01:20 PM
  2. Multiple Source Files, make files, scope, include
    By thetinman in forum C++ Programming
    Replies: 13
    Last Post: 11-05-2008, 11:37 PM
  3. Working with multiple source files
    By abh!shek in forum C Programming
    Replies: 17
    Last Post: 06-03-2008, 11:23 AM
  4. Multiple Source Files!?!?
    By Padawan in forum C Programming
    Replies: 14
    Last Post: 04-04-2004, 12:19 AM
  5. Replies: 1
    Last Post: 05-01-2003, 02:52 PM