0

Hi I'm having trouble sending an array of structures to a function. The structure is set up as below:

struct Leader
{
   char surname[15], party[15];
   int months_in_power;
};

I then read the data from a file and assign it:

if ((INFILE=(fopen("PM.txt","r"))) == NULL) 
{ 
    printf("ERROR: The file could not be opened."); 
    system("pause"); 
    return 1; 
}

while(fscanf(INFILE, "%s %d %d %d %d %s", name, 
&start_month, &start_year, &end_month, &end_year, party)>0)
{
    struct Leader PM[i];
    strcpy(PM[i].surname, name);
    strcpy(PM[i].party, party);
    months = tenure(start_month, start_year, end_month, end_year);
    PM[i].months_in_power = months;
    party_time(&PM[i], &Con_months, &Lab_months );
    printf("%s: %s, %d months\n", PM[i].surname, PM[i].party, PM[i].months_in_power); //This line all works
    i++;
}  

Then I try and call my function 'bubble'.

imax=i;
bubble(PM, imax);

and the function bubble is supposed to sort them in order.

void bubble(struct Leader arr[],int max)
{
    int j=0, i=0, temp=0;

    for (j=1; j<(max);j++)
    {   
        for (i=0; i<(max-1); i++)
        {
        if (arr[i].months_in_power < arr[i+1].months_in_power)
        { 
            temp = arr[i].months_in_power;
            arr[i].months_in_power=arr[i+1].months_in_power;
            arr[i+1].months_in_power = temp;
        }
            else continue;
        }
    } 

    for( i=0; i<max; i++) 
    {printf("%d\n", arr[i].months_in_power);} 

    return ;        
}

If I try and print arr[i].months_in_power during the sorting loops it just prints rubbish and crashes. Whats wrong?

EDIT: The PM.txt file contains information like:

Attlee 7 1945 10 1951 Labour

Churchill 11 1951 5 1955 Conservative

Eden 6 1955 12 1956 Conservative

etc etc...

Thanks

3
  • post a few lines of your data file PM.txt that will help us understand where array overflow may be occurring, if at all. Commented Nov 9, 2014 at 10:48
  • I edited the original question to add a few lines Commented Nov 10, 2014 at 13:18
  • Good, post your tenure() (which looks like it calculates months during tenure?) Commented Nov 10, 2014 at 14:43

2 Answers 2

1

I don't think that the following code is correct

struct Leader PM[i];
strcpy(PM[i].surname, name);
strcpy(PM[i].party, party);

You first declare an array of Leader structures of size i, which can be correct, but then you try to access it with PM[i]. PM[i] will fetch data beyond the array and strcpy will write into memory which doesn't belong to the array.

Later on, when you try to access data it might be garbage.

Sign up to request clarification or add additional context in comments.

1 Comment

I don't think that is an issue. i is controlled by the lines read from the text file PM.txt and cannot cause a read beyond end of data or array.
0

In your code, you did not create an instance of the PM array or structs. Other than a few other nits, and your sort being in descending order (check the bubble sort logic), the code was not in bad shape. Note: when you are creating an array of some size, it is general practice to #define a maximum size of the array. Below, I just defined MAXS (max structures) to 256 in the line #define MAXS 256. You then check your count as you read from your data file against MAXS-1 (zero based array count). If you exceed MAXS - 1 you will need to increase the size (or if you allocated dynamically, you have the option to reallocate at that point) The example below ran fine.

Remember to initialize all variables! This is one of the easiest things you can do to prevent wandering off into undefined behavior.

Note: I created a tenure to return the number of months served -- make sure that is what you want. Also, I did not recreate a party_time function. That's up to you.

Let me know if you need any additional help.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXS 256

struct Leader
{
    char surname[15];
    char party[15];
    int months_in_power;
};

void bubble (struct Leader arr[],int max);
int tenure (int start_month, int start_year, int end_month, int end_year);

int main () {

    char name[64] = {0};
    char party[64] = {0};
    int start_month=0, start_year=0, end_month=0, end_year=0;
    int months = 0;
    int i = 0;
    int imax = 0;
    FILE *INFILE;

    struct Leader PM[MAXS] = {{ {0}, {0}, 0 }};

    if ((INFILE = (fopen ("PM.txt","r"))) == NULL) 
    { 
        fprintf (stderr, "ERROR: The file could not be opened."); 
        return 1; 
    }

    while(fscanf(INFILE, "%s %d %d %d %d %s", name, 
    &start_month, &start_year, &end_month, &end_year, party)>0)
    {
        strcpy(PM[i].surname, name);
        strcpy(PM[i].party, party);
        months = tenure(start_month, start_year, end_month, end_year);
        PM[i].months_in_power = months;
        // party_time(&PM[i], &Con_months, &Lab_months );
        printf("%-12s: %-12s, %d months\n", PM[i].surname, PM[i].party, PM[i].months_in_power); //This line all works

        i++;

        if (i > MAXS - 1) {
            fprintf (stderr, "Error: lines read from file exceed MAXS, reallocate or increase size.\n");
            return 1;
        }
    }

    imax=i;
    bubble(PM, imax);

    return 0;
}

void bubble(struct Leader arr[],int max)
{
    int j=0, i=0, temp=0;

    for (j=1; j<(max);j++)
    {   
        for (i=0; i<(max-1); i++)
        {
        if (arr[i].months_in_power < arr[i+1].months_in_power)
        { 
            temp = arr[i].months_in_power;
            arr[i].months_in_power=arr[i+1].months_in_power;
            arr[i+1].months_in_power = temp;
        }
            else continue;
        }
    } 

    for( i=0; i<max; i++) 
    {printf("%d\n", arr[i].months_in_power);} 

    return ;        
}

int tenure (int start_month, int start_year, int end_month, int end_year) 
{
    int no_months = (end_year - start_year) * 12 - start_month + end_month;
    return (start_year <= end_year) ? no_months : -(no_months);
}

input:

$ cat PM.txt
Attlee 7 1945 10 1951 Labour
Churchill 11 1951 5 1955 Conservative
Eden 6 1955 12 1956 Conservative

output:

$ ./bin/structleader
Attlee      : Labour      , 75 months
Churchill   : Conservative, 42 months
Eden        : Conservative, 18 months
75
42
18

1 Comment

Thanks very much, that sorted everything

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.