user1992348
user1992348

Reputation: 113

Why Does My C Program That Uses A Function To Total Months in a Year Fail?

I've written a program that's gradually grown from a simple structure that holds information about a month, to an array of 12 structures of the same information for a non-leap year. Now, I'm trying to include a function that, "when given the month number, returns the total days in the year up to an including that month. Assume that the structure template of question 3 and an appropriate array of such structures are declared externally."

When I press run I get two errors, neither of which I understand. Here they are: "Undefined symbols for architecture x86_64: "_months", referenced from: _days in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)"

Any help would be greatly appreciated, thanks.

#include <stdio.h>
int days(int monthnum);
struct month {
char name[10];
char abbreviaton[4];
int days;
int monthnum;
};
int main(void)
{

struct month months[12] = {
    {"January", "Jan", 31, 1},
    {"February", "Feb", 28, 2},
    {"March", "Mar", 31, 3},
    {"April", "Apr", 30, 4},
    {"May", "May", 31, 5},
    {"June", "Jun", 30, 6},
    {"July", "Jul", 31, 7},
    {"August", "Aug", 31, 8},
    {"September", "Sep", 30, 9},
    {"October", "Oct", 31, 10},
    {"November", "Nov", 30, 11},
    {"December", "Dec", 31, 12},
};

struct month *sign;

sign = &months[12];

days(months[12].monthnum);

return 0;
}
extern struct month months[12];
int days(int monthnum)
{
int index, total;

if (monthnum < 1 || monthnum > 12)
    return(-1);
else
{
    for (index = 0, total = 0; index < monthnum; index++)
        total += months[index].days;
return(total);
}
}

Here is the code I have now. The program works:

#include <stdio.h>
int days(int monthnum);
struct month {
char name[10];
char abbreviaton[4];
int days;
int monthnum;
};
struct month months[12] = {
    {"January", "Jan", 31, 1},
    {"February", "Feb", 28, 2},
    {"March", "Mar", 31, 3},
    {"April", "Apr", 30, 4},
    {"May", "May", 31, 5},
    {"June", "Jun", 30, 6},
    {"July", "Jul", 31, 7},
    {"August", "Aug", 31, 8},
    {"September", "Sep", 30, 9},
    {"October", "Oct", 31, 10},
    {"November", "Nov", 30, 11},
    {"December", "Dec", 31, 12},
};
int main(void)
{
int value;
int count = 0;
struct month *sign;

sign = &months;

printf("Enter month number: ");

scanf("%d", &months[count].monthnum);

value = days(sign->monthnum);

printf("%d", value);

return 0;
}
extern struct month months[];
int days(int monthnum)
{
int index, total;

if (monthnum < 1 || monthnum > 12)
    return(-1);
else
{
    for (index = 0, total = 0; index < monthnum; index++)
        total += months[index].days;
return(total);
}
}

Upvotes: 0

Views: 136

Answers (2)

Ed Swangren
Ed Swangren

Reputation: 124732

The immediate problem is due to this line;

extern struct month months[12];

There is no array definition to reference here; months is declared inside of main, nowhere else. Get rid of that line.

Next you have logical issues:

days(months[12].monthnum);

You have overrun the bounds of your array. Arrays are 0 indexed, i.e., an array of twelve elements contains valid indices 0-11. 12 is one too far.

As an aside, you do not need to specify the dimension of an array when you are explicitly initializing each element. Just use:

struct month months[] = {
    {"January", "Jan", 31, 1},
    {"February", "Feb", 28, 2},
    {"March", "Mar", 31, 3},
    {"April", "Apr", 30, 4},
    {"May", "May", 31, 5},
    {"June", "Jun", 30, 6},
    {"July", "Jul", 31, 7},
    {"August", "Aug", 31, 8},
    {"September", "Sep", 30, 9},
    {"October", "Oct", 31, 10},
    {"November", "Nov", 30, 11},
    {"December", "Dec", 31, 12},
};

The compiler knows that there are twelve elements because you told it so. Now you don't have to change the dimension when/if you add or remove an element.

Next problem; variable scope. You have this inside of your days function:

total += months[index].days;

Well, days has no access to months because months is local to main. You need to study and understand variable scope.

Upvotes: 2

aragaer
aragaer

Reputation: 17858

extern struct month months[12]; means you have a global array months defined somewhere. Your months array is not global, it is local to your main function. That's the error. Other message is not a second error.

You should also note that you shouldn't access months[12] since you only have 12 elements in that array - months[0] to months[11].

Upvotes: 2

Related Questions