0

I had to write a program to do this, This is a program that will sort information on when the TAs for COP 3223 are available. The program is expected to read in data on all TA office hour shifts, then sort the data, and then print out the information in a pre-specified format. It is assumed that the maximum number of shifts is 100.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Given structure format that is needed to be used in the program. */
struct Shift
{
char name[100];
char day_of_week[100];
int start_hour;
int end_hour;
};

/* Functions that will be used in the program. */
int read_data(struct Shift shift_data[], int *num_shifts);
void sort_data(struct Shift shift_data[], int *num_shifts);
void print_data(struct Shift shift[], int num_shifts);

int main(void)
{
struct Shift shift_data[100];
struct Shift temp;

/*Declare and initialize variables, and statements to call each function. */
int num_shifts;

read_data(shift_data, &num_shifts);

sort_data(shift_data, &num_shifts);

print_data(shift_data, num_shifts);

return 0;
}

/*** Preconditions: array of structure "Shift" to store data
 Postconditions: number of shifts read in from data file
 Actions: Ask user for name of input file. Read the number of shifts, then read in the data for all
          of the shifts. Return the number of shifts. ***/
int read_data(struct Shift shift_data[], int *num_shifts)
{
/*Declare and initialize variables. */
char input_schedule[100];
int i;
char shift_name[100], shift_day[100];
/*Prompt user to enter the input file. */
printf("Enter the name of the file name.\n");
scanf("%s", &input_schedule[100]);
/*Declare file and read in the needed values. */
FILE *ifp;
ifp = fopen("input_schedule.txt", "r");
fscanf(ifp, "%d", &num_shifts);
/*For loop to read in each value from the file and store them in the shift_data array. */
for(i=0; i<(*num_shifts); i++)
{
     fscanf(ifp, "%s %s %d %d\n", &shift_data[i].name, &shift_data[i].day_of_week, &shift_data[i].start_hour, &shift_data[i].end_hour);
}
/*Close file.*/
fclose(ifp);

return num_shifts;
}
/*** Preconditions: array of structure "Shift" integer value indicating number of shifts
 Postconditions: none - this function does not return anything.
 Actions: Sort the shifts by the TA's first name. ***/
void sort_data(struct Shift shift_data[], int *num_shifts)
{
/*Declare and initialize variables. */
int i,j;
/*For loop to run through each array.*/
for(i=0; i<(*num_shifts); i++)
{
/*For loop to use the next element in the array to compare to the element before it.*/
    for(j=i+1; j<(*num_shifts); j++)
    {
/*If statements using strcmp to compare the two strings and sort the data in order.*/
        if(strcmp(shift_data[i].name,shift_data[i].name) < 0)
        {
            memcpy(temp.name, shift_data[i].name, strlen(shift_data[i].name) + 1);
            memcpy(shift_data[i].name, shift_data[j].name, strlen(shift_data[j].name) + 1);
            memcpy(shift_data[j].name, temp.name, strlen(temp.name) + 1);
        }
        if(strcmp(shift_data[i].day_of_week,shift_data[i].day_of_week) < 0)
        {
            temp.day_of_week = shift_data[i].day_of_week;
            shift_data[i].day_of_week = shift_data[j].day_of_week;
            shift_data[j].day_of_week = temp.day_of_week;
        }
        if(strcmp(shift_data[i].start_hour,shift_data[i].start_hour) < 0)
        {
            temp.start_hour = shift_data[i].start_hour;
            shift_data[i].start_hour = shift_data[j].start_hour;
            shift_data[j].start_hour = temp.start_hour;
        }
        if(strcmp(shift_data[i].end_hour,shift_data[i].end_hour) < 0)
        {
            temp.end_hour = shift_data[i].end_hour;
            shift_data[i].end_hour = shift_data[j].end_hour;
            shift_data[j].end_hour = temp.end_hour;
        }
    }

}
}

/*** Preconditions: array of structure "Shift" integer value indicating number of shifts
 Postconditions: none - this function does not return anything.
 Actions: Print the sorted data in the format described below. **/
void print_data(struct Shift shift_data[], int num_shifts)
{
/*Declare and initialize variables.*/
int i;

printf("\n\n\n");
/*For loop to print out the sorted data to the user.*/
for(i=0; i<num_shifts; i++)
{
    printf("%s\t\t", shift_data[i].name);
    printf("%s\t", shift_data[i].day_of_week);
    printf("%d to ", shift_data[i].start_hour);
    printf("%d\n", shift_data[i].end_hour);
/*If statements to change the shift times from military time to standard time.*/
    if(shift_data[i].start_hour > 12)
    {
        shift_data[i].start_hour = shift_data[i].start_hour - 12;
        printf("%2d:00 pm to  ", shift_data[i].start_hour);
    }
    else if(shift_data[i].start_hour < 12)
    {
        printf("%2d:00 am to  ", shift_data[i].start_hour);
    }
    else if(shift_data[i].start_hour == 12)
    {
        printf("%2d:00 pm to  ", shift_data[i].start_hour);
    }

    if(shift_data[i].end_hour > 12)
    {
        shift_data[i].end_hour = shift_data[i].end_hour - 12;
        printf("%2d:00 pm\n", shift_data[i].end_hour);
    }
    else if(shift_data[i].end_hour < 12)
    {
        printf("%2d:00 am\n", shift_data[i].end_hour);
    }
    else if(shift_data[i].end_hour == 12)
    {
        printf("%2d:00 pm\n", shift_data[i].end_hour);
    }
}
}

The problem I am having is in the sort_data function. I keep getting an error that says incompatibable types when assigning to type 'char[100]' from type 'char *'. It's with my temp variable, but I can't seem to figure out how to fix it.

15
  • It would be good to state exactly which line(s) of code is giving you the error. I assume this one: shift_data[j].name = temp.name;. You cannot change the value of an array itself. To change the contents of the array you probably want strncpy(shift_data[j].name, temp.name, sizeof(shift_data[j].name)) Commented Dec 4, 2015 at 1:02
  • I think you do not know what you are doing here: if(strcmp(shift_data[i].start_hour,shift_data[i].start_hour) < 0). You should do if(shift_data[i].start_hour < shift_data[i].start_hour). Commented Dec 4, 2015 at 1:08
  • 1
    scanf("%s", &input_schedule[100]); is a blunder. You just told it to start writing after the end of the array... Instead it should be scanf("%99s", input_schedule) Commented Dec 4, 2015 at 3:15
  • fscanf(ifp, "%d", &num_shifts); is also an error. Think about what num_shifts is. Commented Dec 4, 2015 at 3:15
  • You have many lines where you strcmp a string with itself - this will always match Commented Dec 4, 2015 at 3:16

2 Answers 2

2

When you make an assignment with array of char in C, it will not copy the content of the array.

Instead of use:

temp.name = shift_data[i].name;

do:

strncpy(temp.name, shift_data[i].name, 99);
temp.name[99] = '\0';

I'm sorry, I advised you to use memcpy(), but you have to check the lenght of the string to know how many bytes to copy and is not the correct function to use.

Using strncpy is better, because the copy stops when reach a null byte or the maximum number of characters that can be stored. Note, the lenght of your string is 100. The 99 will make strncpy copy from index 0 to 98 in your string. And the line temp.name[99] = '\0'; will fill the last position of your string with \0.

On this page: http://linux.die.net/man/3/strncpy, has a better description about strncpy and a simple code for this function.

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

Comments

-1

The problem with your code is that arrays can't be copied (for some reason). On the other hand structures can and simply casting your array into a structure containing an array with the same size will do the job.

It will look something like this:

typedef struct { char day_of_week[100]; } tmpType;

*(tmpType*)temp.day_of_week = *(tmpType*)shift_data[i].day_of_week;

This way you avoid calling external library functions (for some compilers).

If you want more info about arrays I suggest you search 'array to pointer decay' in Google.

But another problem I'm suspecting in your code is that your 'temp' variable isn't defined in the scope of the function 'sort_data', where you use it.

I guess you meant to make it a global variable. If this is the case you must define it outside of main, something like this:

struct Shift temp;

int main(void)
{
/*your main code*/
}

Your fixed function should look something like this:

void sort_data(struct Shift shift_data[], int *num_shifts)
{

typedef struct { char arr[100]; } tmpType;

/*Declare and initialize variables. */
int i,j;
/*For loop to run through each array.*/
for(i=0; i<(*num_shifts); i++)
{
/*For loop to use the next element in the array to compare to the element before it.*/
    for(j=i+1; j<(*num_shifts); j++)
    {
/*If statements using strcmp to compare the two strings and sort the data in order.*/
        if(strcmp(shift_data[i].name,shift_data[i].name) < 0)
        {
            memcpy(temp.name, shift_data[i].name, strlen(shift_data[i].name) + 1);
            memcpy(shift_data[i].name, shift_data[j].name, strlen(shift_data[j].name) + 1);
            memcpy(shift_data[j].name, temp.name, strlen(temp.name) + 1);
        }
        if(strcmp(shift_data[i].day_of_week,shift_data[i].day_of_week) < 0)
        {
            *(tmpType*)temp.day_of_week = *(tmpType*)shift_data[i].day_of_week;
            *(tmpType*)shift_data[i].day_of_week = *(tmpType*)shift_data[j].day_of_week;
            *(tmpType*)shift_data[j].day_of_week = *(tmpType*)temp.day_of_week;
        }
        if(strcmp(shift_data[i].start_hour,shift_data[i].start_hour) < 0)
        {
            temp.start_hour = shift_data[i].start_hour;
            shift_data[i].start_hour = shift_data[j].start_hour;
            shift_data[j].start_hour = temp.start_hour;
        }
        if(strcmp(shift_data[i].end_hour,shift_data[i].end_hour) < 0)
        {
            temp.end_hour = shift_data[i].end_hour;
            shift_data[i].end_hour = shift_data[j].end_hour;
            shift_data[j].end_hour = temp.end_hour;
        }
    }

}
}

You could also use similar approach for copying your 'name' member if you prefer.

1 Comment

The problem here is that this still doesn't sort the list properly (and if you fixed the code to actually sort the list properly , then this cast would not be necessary)

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.