I have 3 files. variables.h, variables.c, and dictionary_test.c. How would I use my variables.c to get information from variables.h and dictionary_test.c? I'm not supposed to touch the variables.h and dictionary_test.c. I gotta do all the work in variables.c. This is the variables.h.

#define MAX_VARIABLE_LENGTH 15

/* Set the variable with the specified name to the specified value.
 * If there is not a variable with that name in the dictionary,
 * add one. */
void set_variable (const char* name, double value);


/* Return the value of the variable with the specified name.
 * If variable does not exist, add it to the dictionary
 * with a default value of 0.0, and return that value. */
double variable_value(const char* name);


/* Display the names and values of all variables in the dictionary. */
void display_variables();

This is the dictionary_test.c.

#include <stdio.h>
#include "variables.h"

void verify (double result, double expected_value)
{
    if (result != expected_value)
    {
        printf ("Incorrect result.  Should be %8.4f\n\n", expected_value);
    }
}

int main()
{
    double result;

    printf ("Starting dictionary test\n\n");
    set_variable("A1", 1.0);
    set_variable("A2", 2.0);
    set_variable("A3_3333", 3.3333);

    result = variable_value("A1");
    printf ("A1 is %8.4f.\n", result);
    verify(result, 1.0);

    result = variable_value("A2");
    printf ("A2 is %8.4f.\n", result);
    verify(result, 2.0);

    result = variable_value("A3_3333");

    printf ("A3_333 is %8.4f\n", result);
    verify(result, 3.3333);

    set_variable("A long variable", -1.0);
    result = variable_value("A long variable");
    printf ("A long variable is %8.4f\n", result);
    verify(result, -1.0);

    result = variable_value("Unset Variable ");
    printf ("Unset Variable  is %8.4f\n", result);
    verify(result, 0.0);

    printf ("\n");
    printf ("All variables:\n");
    display_variables();

    printf ("Dictionary test complete\n");
    getchar();
    return 0;
}

And this is the start to variables.c.

#include <stdio.h>


int main()
{

    return 0;
}

I was given the variables.h and dictionary_test.c. and it won't even compile and I can't even change it. Here are the errors I get.
gcc -Wall *.c
/tmp/cceDui0k.o: In function `main':
dictionary_test.c:(.text+0x60): undefined reference to `set_variable'
dictionary_test.c:(.text+0x7d): undefined reference to `set_variable'
dictionary_test.c:(.text+0x9a): undefined reference to `set_variable'
dictionary_test.c:(.text+0xa4): undefined reference to `variable_value'
dictionary_test.c:(.text+0xf1): undefined reference to `variable_value'
dictionary_test.c:(.text+0x149): undefined reference to `variable_value'
dictionary_test.c:(.text+0x1b4): undefined reference to `set_variable'
dictionary_test.c:(.text+0x1be): undefined reference to `variable_value'
dictionary_test.c:(.text+0x216): undefined reference to `variable_value'
dictionary_test.c:(.text+0x273): undefined reference to `display_variables'
collect2: ld returned 1 exit status


Any ideas and help would be greatly appreciated.

Member Avatar for tcstom

You have to create the functions:
set_variable()
variable_value()
and
display_variables()
in variables.c

the green text explains what the functions do.

I would reccomend creating a linked list of "variables" if you want to be able to add variables
Or if the dictionary is fixed i would use an array of structs

set_variable() will search the array and change the value
variable_vaule() will search the array and return the value
display_variables() will printf() al the variables

dictionary_test.c is the main function (hence it contains main()) this is the one you run

commented: good +7

your variables.c file should NOT have a "main()" function. your variables.c file should have ONLY the implementation of the three functions prototyped in variables.h.

the two files, variables.c and variables.h are a pair. the .h declares the prototypes, the .c defines the implementation. you may not be used to seeing .h files, they are not strictly necessary. but you will find they are increasingly important as your projects get bigger and more files are involved.

the "dictionary_test" file is the file that has the "main()" routine. this is the entry point when the program is executed. this file will have the "#include variables.h" which links the functions compiled from the "variables.c" that you will write, so that those functions can be used in the program.

your job now is to write these three functions, put them in the "variables.c" file, and write them strictly according to the prototypes declared in "variables.h"

here is the start of your variables.c file:

#include <stdio.h>


void set_variable (const char* name, double value)
{


    return;
}
double variable_value(const char* name)
{


    return 0;
}

void display_variables()
{


    return;
}

your project will now compile without errors. it won't do anything, and likely may crash with a runtime error until you actually write the functions to do what is expected, but it will compile.

try to understand this general method. if you ever get a job programming, this is likely how you will be assigned work to do: to write functions that are prototyped by someone else (a senior programmer or architect), and the functions you will write must strictly adhere to the specifications as they will be called by any number of higher level applications.

You have to create the functions:
set_variable()
variable_value()
and
display_variables()
in variables.c

the green text explains what the functions do.

I would reccomend creating a linked list of "variables" if you want to be able to add variables
Or if the dictionary is fixed i would use an array of structs

set_variable() will search the array and change the value
variable_vaule() will search the array and return the value
display_variables() will printf() al the variables

dictionary_test.c is the main function (hence it contains main()) this is the one you run

Sounds like you have had this project before. Is that correct?

your variables.c file should NOT have a "main()" function. your variables.c file should have ONLY the implementation of the three functions prototyped in variables.h.

the two files, variables.c and variables.h are a pair. the .h declares the prototypes, the .c defines the implementation. you may not be used to seeing .h files, they are not strictly necessary. but you will find they are increasingly important as your projects get bigger and more files are involved.

the "dictionary_test" file is the file that has the "main()" routine. this is the entry point when the program is executed. this file will have the "#include variables.h" which links the functions compiled from the "variables.c" that you will write, so that those functions can be used in the program.

your job now is to write these three functions, put them in the "variables.c" file, and write them strictly according to the prototypes declared in "variables.h"

here is the start of your variables.c file:

#include <stdio.h>


void set_variable (const char* name, double value)
{


    return;
}
double variable_value(const char* name)
{


    return 0;
}

void display_variables()
{


    return;
}

your project will now compile without errors. it won't do anything, and likely may crash with a runtime error until you actually write the functions to do what is expected, but it will compile.

try to understand this general method. if you ever get a job programming, this is likely how you will be assigned work to do: to write functions that are prototyped by someone else (a senior programmer or architect), and the functions you will write must strictly adhere to the specifications as they will be called by any number of higher level applications.

Thank you for the help to get me started. I have a few warnings with my current code.

variables.c: In function âset_variableâ:
variables.c:35: warning: initialization from incompatible pointer type
variables.c: In function âvariable_valueâ:
variables.c:64: warning: control reaches end of non-void function
variables.c: At top level:
variables.c:18: warning: ânodeâ defined but not used

Not sure how I have incompatible pointer types. I know I need to return something in variable_value, but not sure what to return :(. I don't understand how node is not used when I am using it on line on line 35.

#include <assert.h>
#include <stdio.h>
#include "variables.h"
#include <string.h>
#include <stdlib.h>

//Defining Variable as suggested with slide
typedef struct
{
    char key[15];
    double value;
} Variable_t;

//My static function
static Variable_t node = {"", 0.0};

//Defining Node struct for linked list
typedef struct String_Node
{
    struct String_Node* next;
    struct String_Node* prev;
    Variable_t val;
} String_Node_t;

//My other static function
static String_Node_t list_head = {&list_head, &list_head, {"", 0}};
      
/* Allocate memory for a String_Node_t struct and initialize the struct
* with values passed by the caller. */
void set_variable (const char* name, double value)
{
    Variable_t* node = {""};
    String_Node_t* new_name = malloc(sizeof(String_Node_t));
    printf ("new value and name called for %lg: %s\n", value, name);
    
    assert(new_name != NULL);
    node->value = value;
    node->key[15] = *name;

    new_name->next = NULL;
    new_name->prev = NULL;
    new_name->val = *node;

}
//Function to return values
double variable_value(const char* name)
{
    String_Node_t* pointer = &list_head;
    do
    {
        if (strcmp(pointer->val.key, name))
        {
            return (pointer->val.value);
        }
        else if (pointer->val.value == 0)
        {
        return (pointer->val.value);
        }
        pointer = pointer->next;
    }while (strcmp(pointer->val.key, "end"));
}
//Function to display the variables

void display_variables()
{

    String_Node_t* p = list_head.next;
    if (p == &list_head)
    {
        printf ("List is empty\n");
    }
    else
    {
        while (p != &list_head)
        {
            printf("\n");
            p = p->next;
        }
    }
    printf ("%lg %s\n", p->val.value, p->val.key);
    return;
}

Ok I have 3 parts. I really can't figure out what my problem is. My current warnings are below.
variables.c: In function âset_variableâ:
variables.c:35: warning: initialization from incompatible pointer type
variables.c: In function âvariable_valueâ:
variables.c:66: warning: control reaches end of non-void function
variables.c: At top level:
variables.c:18: warning: ânodeâ defined but not used

I also get a segmentation fault which I believe is usually caused by pointer problems. I'm not sure how to fix it.

dictionary.c

#include <stdio.h>
#include "variables.h"

void verify (double result, double expected_value)
{
    if (result != expected_value)
    {
        printf ("Incorrect result.  Should be %8.4f\n\n", expected_value);
    }
}

int main()
{
    double result;

    printf ("Starting dictionary test\n\n");
    set_variable("A1", 1.0);
    set_variable("A2", 2.0);
    set_variable("A3_3333", 3.3333);

    result = variable_value("A1");
    printf ("A1 is %8.4f.\n", result);
    verify(result, 1.0);

    result = variable_value("A2");
    printf ("A2 is %8.4f.\n", result);
    verify(result, 2.0);

    result = variable_value("A3_3333");

    printf ("A3_333 is %8.4f\n", result);
    verify(result, 3.3333);

    set_variable("A long variable", -1.0);
    result = variable_value("A long variable");
    printf ("A long variable is %8.4f\n", result);
    verify(result, -1.0);

    result = variable_value("Unset Variable ");
    printf ("Unset Variable  is %8.4f\n", result);
    verify(result, 0.0);

    printf ("\n");
    printf ("All variables:\n");
    display_variables();

    printf ("Dictionary test complete\n");
    getchar();
    return 0;
}

*****************************************************************************
variables.h

#define MAX_VARIABLE_LENGTH 15

/* Set the variable with the specified name to the specified value.
 * If there is not a variable with that name in the dictionary,
 * add one. */
void set_variable (const char* name, double value);


/* Return the value of the variable with the specified name.
 * If variable does not exist, add it to the dictionary
 * with a default value of 0.0, and return that value. */
double variable_value(const char* name);


/* Display the names and values of all variables in the dictionary. */
void display_variables();

******************************************************************************
variables.c

#include <assert.h>
#include <stdio.h>
#include "variables.h"
#include <string.h>
#include <stdlib.h>

//Defining Variable as suggested with slide
typedef struct
{
    char key[15];
    double value;
} Variable_t;

//My static function
static Variable_t node = {"", 0.0};

//Defining Node struct for linked list
typedef struct String_Node
{
    struct String_Node* next;
    struct String_Node* prev;
    Variable_t val;
} String_Node_t;

//My other static function
static String_Node_t list_head = {&list_head, &list_head, {"", 0}};
      
/* Allocate memory for a String_Node_t struct and initialize the struct
* with values passed by the caller. */
void set_variable (const char* name, double value)
{
    //I'm not sure which method to use. 
	Variable_t* node = {""};
	//Variable_t node = {""};
	//Variable_t* node = NULL;
    String_Node_t* new_name = malloc(sizeof(String_Node_t));
    printf ("new value and name called for %lg: %s\n", value, name);
    
    assert(new_name != NULL);
    node->value = value;
    node->key[15] = *name;

    new_name->next = NULL;
    new_name->prev = NULL;
    new_name->val = *node;

}
//Function to return values
double variable_value(const char* name)
{
    String_Node_t* pointer = &list_head;
    do
    {
        if (strcmp(pointer->val.key, name))
        {
            return (pointer->val.value);
        }
        else if (pointer->val.value == 0)
        {
        return (pointer->val.value);
        }
        pointer = pointer->next;
    }while (strcmp(pointer->val.key, "end"));
}
//Function to display the variables

void display_variables()
{

    String_Node_t* p = list_head.next;
    if (p == &list_head)
    {
        printf ("List is empty\n");
    }
    else
    {
        while (p != &list_head)
        {
            printf("\n");
            p = p->next;
        }
    }
    printf ("%lg %s\n", p->val.value, p->val.key);
    return;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.