Solved

stack of queues

Posted on 2008-10-22
174
610 Views
Last Modified: 2010-04-21
I have a homework assignment in C. I am suppose to have a train station that has trains(stacks) and cars(queues) in it. When they are to depart I am suppose to print out that they have departed also I should add a car remove a car and print that out as well. I am lost with wirting the function that does this.
Here is the code that I have up to this point if anyone can help that would be great.

if this is removed the program runs.
int remove_car(struct train* q)
{
      if (
            isQueueEmpty(s)
            printf("there is only one car on the train.");
}
any ideas would be great

/*George Regas

  COP 3502

  g0616085

  Oct 22, 2008

  Assignment 3:

  Bob's Train Station

*/

#include <stdio.h>
 

struct station* new_station(int initial_Size);

struct train* new_train(int initial_size);	

void print_stack(struct station* s);

void print_queue(struct train* q);

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);

int remove(struct station* s, struct train* q);

int last_car(struct queue* q);
 

struct train

{

    int* store;

    int front;

    int back;

    int size;

};
 

struct station

{

    struct train * store;

    int top;

    int size;

};
 

struct station* new_station(int initial_Size) //my stack

{

    struct station* s;

    

    s = malloc(sizeof(struct station));

    

    s->store = calloc(initial_Size, sizeof(struct train));

    s->top = 0;

    s->size = initial_Size;

    

    return s;

}
 

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;
 

printf("Train Departed: ");
 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		printf("%d ", car);

        q->store[q->back] = car;

        q->back = (q->back + 1) % q->size;

        //expand queue check

    }

printf("\n");
 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}
 

struct train* new_train(int initial_size) //my queue

{

    struct train* q;

    

    q = malloc(sizeof(struct train));

    q->store = calloc(initial_size, sizeof(int));

    q->front = 0;

    q->back = 0;

    q->size = initial_size;

    

    return q;   

}
 

void print_queue(struct train* q)

{

	int i;

	

	for(i=q->front; i < q->back; i++)

		printf("%d", q->store[i]);
 

}

void print_stack(struct station* s)

{

    int i; // index used in for loop

    

    // loop through stack from top to bottom, printing them out as we go

    for(i = 0; i < s->top; i++)

        print_queue;

       

}

// This function returns true if the queue is empty and false otherwise

int isQueueEmpty(struct train* q)

{

    // if the front and back are equal to each other then the queue is empty

    return q->front == q->back;   

}

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    // Move front up one position in the store array

    // The % (modulus) operator is used to ensure that front does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->front = (q->front + 1) % q->size;

    

    // return the value that just got dequeued

    return rval;

}

int remove_car(struct train* q)

{

	if (

		isQueueEmpty(s)

		printf("there is only one car on the train.");

}

int main(void)

{

	FILE *fp;

    char fname[32];	

	int i, n;

	char action[20];

	struct station* s;

	struct train* q;

	int num_cars;
 

	printf("Welcome to Bob's Train Station\n");

	printf("What is the name of the input file?\n");

	scanf("%s", fname);
 

	fp = fopen(fname, "r");

	if (fp == NULL)

		printf("ERROR");

	

	printf("Here is the output!:\n");

	

	fscanf(fp, "%d", &n);

	s=new_station(10);

	for(i=0; i<n; i++)

	{

		fscanf(fp,"%s", action);

		if(strcmp(action,"new_train")==0)

		{

			fscanf(fp, "%d", &num_cars);

			q=new_train(num_cars);				

			add_train(s, q, num_cars, fp);

		}

/*		else if(strcmp(action, "remove_car")==0);

		{

			place funtion here

		}

		else if(strcmp(action, "add_car")==0);

		{

			place funtion here

		}

		else if(strcmp(action, "train_departs")==0);

		{

			place funtion here

		}//*/

	}

	fclose(fp);

		

	system("PAUSE");

	return 0;

}

Open in new window

0
Comment
Question by:mikeregas
  • 86
  • 84
  • 4
174 Comments
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
Cars are in a queue and you need functions to add/delete from queue

Addition()
{
    check if addition would lead to overflow - i.e. you should not be trying to insert more elements than the queue can handle. If that is the case, return error

    add an element to the end of the queue

    return success
}

Deletion()
{
    check for underflow ... i.e. are you trying to delete from empty queue. if yes then return error

    remove element from head of the queue

    return success
}

struct train
{
    int* store;
    int front;
    int back;
    int size;
};

Your queue would be a dynamically allocated array ... so you would need a circular queue kind of implementation in order to reuse the array locations. Whenever your front or back reach max value, you need to reset them to 0. one way of doing that is %capacity every time you increment them
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
I see some initial problems

The prototype
   int remove(struct station* s, struct train* q); //<<
differs in signature (has two arguments) from the function
   int remove_car(struct train* q)

In the remove_car function
   if (isQueueEmpty(s)
uses an undefined variable s, and should be
  if (isQueueEmpty(q))
Note added close parenthesis

I'll look further.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Would you please post the input file  you are using?
0
 

Author Comment

by:mikeregas
Comment Utility
what am I doing worng in the function int remove_car()?
/*George Regas

  COP 3502

  g0616085

  Oct 22, 2008

  Assignment 3:

  Bob's Train Station

*/

#include <stdio.h>
 

struct station* new_station(int initial_Size);

struct train* new_train(int initial_size);	

void print_stack(struct station* s);

void print_queue(struct train* q);

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);

int last_car(struct queue* q);

int isQueueEmpty(struct train* q);
 

struct train

{

    int* store;

    int front;

    int back;

    int size;

};
 

struct station

{

    struct train * store;

    int top;

    int size;

};
 

struct station* new_station(int initial_Size) //my stack

{

    struct station* s;

    

    s = malloc(sizeof(struct station));

    

    s->store = calloc(initial_Size, sizeof(struct train));

    s->top = 0;

    s->size = initial_Size;

    

    return s;

}
 

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;
 

printf("Train Departed: ");
 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		printf("%d ", car);

        q->store[q->back] = car;

        q->back = (q->back + 1) % q->size;

        //expand queue check

    }

printf("\n");
 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}
 

struct train* new_train(int initial_size) //my queue

{

    struct train* q;

    

    q = malloc(sizeof(struct train));

    q->store = calloc(initial_size, sizeof(int));

    q->front = 0;

    q->back = 0;

    q->size = initial_size;

    

    return q;   

}
 

void print_queue(struct train* q)

{

	int i;

	

	for(i=q->front; i < q->back; i++)

		printf("%d", q->store[i]);
 

}

void print_stack(struct station* s)

{

    int i; // index used in for loop

    

    // loop through stack from top to bottom, printing them out as we go

    for(i = 0; i < s->top; i++)

        print_queue;

       

}

// This function returns true if the queue is empty and false otherwise

int isQueueEmpty(struct train* q)

{

    // if the front and back are equal to each other then the queue is empty

    return q->front == q->back;   

}

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    // Move front up one position in the store array

    // The % (modulus) operator is used to ensure that front does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->front = (q->front + 1) % q->size;

    

    // return the value that just got dequeued

    return rval;

}

int remove_car(struct train* q)

{

	if(isQueueEmpty(q)==1)

	{

		printf("There is only one car on the train.\n");

		return q;

	}
 

	else if(remove_car)

	{

		dequeue(q);

		printf("Car %d has been removed!\n", &q);

	}

}

int main(void)

{

	FILE *fp;

    char fname[32];	

	int i, n;

	char action[20];

	struct station* s;

	struct train* q;

	int num_cars;
 

	printf("Welcome to Bob's Train Station\n");

	printf("What is the name of the input file?\n");

	scanf("%s", fname);
 

	fp = fopen(fname, "r");

	if (fp == NULL)

		printf("ERROR");

	

	printf("Here is the output!:\n");

	

	fscanf(fp, "%d", &n);

	s=new_station(10);

	for(i=0; i<n; i++)

	{

		fscanf(fp,"%s", action);

		if(strcmp(action,"new_train")==0)

		{

			fscanf(fp, "%d", &num_cars);

			q=new_train(num_cars);				

			add_train(s, q, num_cars, fp);

		}

		else if(strcmp(action, "remove_car")==0);

		{

			remove_car(q);

		}

	/*	else if(strcmp(action, "add_car")==0);

		{

			place funtion here

		}

		else if(strcmp(action, "train_departs")==0);

		{

			place funtion here

		}//*/

	}

	fclose(fp);

		

	system("PAUSE");

	return 0;

}

	

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
here is the input file
10

new_train 5 3 2 4 1 6

new_train 2 4 14

remove_car

remove_car

new_train 3 6 7 8 

train_departs

add_car 15

train_departs

train_departs

train_departs

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
there is alot more that I need to work out, but I am trying to do it one piece at a time. Here is what the output should look like
Sample Run

Welcome to Bob's train station

What is the name of the input file?

sample1.txt

Here is the output:

Car 4 removed!

Car not removed because there is only one car on the train!

Train departed: 6 7 8

Train departed: 14 15

Train departed: 3 2 4 1 6

Station empty, no train departed!

Open in new window

0
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
The function looks correct ... I am not too certain of your queue initialization though ...
You should not be throwing an error in case there is a car to remove ... even if there is one car you should be able to remove it

There are several ways of easily handling this. One is to have a counter member in struct to keep track of number of used locations. So your underflow check becomes counter ==0 and overflow check is counter==capacity. You need to update counter after each addition and deletion. Another way is to make back point to next available location and front to next element to be deleted - so your front would be initialized to -1 and back to 0 - I would leave it up to you to figure out the overflow and underflow ;-)
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Remove the semicolon at the end of
            else if(strcmp(action, "remove_car")==0);
0
 

Author Comment

by:mikeregas
Comment Utility
I know I am a pain I have been working on this since about noon, my brain is fried and I am not seeing what I should be. Therefor nothing is making much since at this point.. I have done what josgood said and the program compiles, however it is not outputting properly.
0
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
>however it is not outputting properly.
It always help if you post some diagnostics - at least the output. that way we dont have scan the code for potential problems. Output gives good clues as to what problem could be.

I am in a rush right now but in about a couple of hours I shall be checking back. In case you edit your code, do post the latest one
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Since this is homework, I must restrict myself to guiding you...I can't just give you the answer.

new_train should not print "Train Departed".  That should be done in your handling of the train_departs command.

remove_ca is confused about its return.  Since no code is using the return value, I suggest changing the return from "int" to "void" and removing the "return q".  I also suggest that "      else if(remove_car)" is incorrect -- you probably want to check whether "q" is null.

Also in remove_car, the "      printf("Car %d has been removed!\n", &q);" needs to print something other than "q", which is not an integer.

See how far that takes you, and then let me know where you are.
0
 

Author Comment

by:mikeregas
Comment Utility
q cannot be NULL it has to be at least one car or q. there cannot be a train with no cars. I think that I am just making these functions harder than they need to be for my purposes.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
In real life, of course, a train can have no cars.  If the homework assignment states that every train will have at least one car, then of course you can take advantage of that.

What does your output look like now?  Could you post the code as you currently have it?
0
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
I tried the code you posted in http:#22782537
The code does not compile ... have you got the compilation issues resolved? If yes then can you post your latest code?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Sunny, we have the compilation issues resolved and and working through the logic.
0
 

Author Comment

by:mikeregas
Comment Utility
this is where I am as of now, still confused as hell. I know that I need to call functions in order to make all of this come together, but they are becoming more and more confusing.
/*George Regas

  COP 3502

  g0616085

  Oct 22, 2008

  Assignment 3:

  Bob's Train Station

*/

#include <stdio.h>
 

struct station* new_station(int initial_Size);

struct train* new_train(int initial_size);	

void print_stack(struct station* s);

void print_queue(struct train* q);

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);

int last_car(struct queue* q);

int isQueueEmpty(struct train* q);
 

struct train

{

    int* store;

    int front;

    int back;

    int size;

};
 

struct station

{

    struct train * store;

    int top;

    int size;

};
 

struct station* new_station(int initial_Size) //my stack

{

    struct station* s;

    

    s = malloc(sizeof(struct station));

    

    s->store = calloc(initial_Size, sizeof(struct train));

    s->top = 0;

    s->size = initial_Size;

    

    return s;

}
 

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;
 

printf("Train Departed: ");
 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		printf("%d ", car);

        q->store[q->back] = car;

        q->back = (q->back + 1) % q->size;

        //expand queue check

    }

printf("\n");
 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}
 

struct train* new_train(int initial_size) //my queue

{

    struct train* q;

    

    q = malloc(sizeof(struct train));

    q->store = calloc(initial_size, sizeof(int));

    q->front = 0;

    q->back = 0;

    q->size = initial_size;

    

    return q;   

}
 

void print_queue(struct train* q)

{

	int i;

	

	for(i=q->front; i < q->back; i++)

		printf("%d", q->store[i]);
 

}

void print_stack(struct station* s)

{

    int i; // index used in for loop

    

    // loop through stack from top to bottom, printing them out as we go

    for(i = 0; i < s->top; i++)

        print_queue;

       

}

// This function returns true if the queue is empty and false otherwise

int isQueueEmpty(struct train* q)

{

    // if the front and back are equal to each other then the queue is empty

    return q->front == q->back;   

}

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    // Move front up one position in the store array

    // The % (modulus) operator is used to ensure that front does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->front = (q->front + 1) % q->size;

    

    // return the value that just got dequeued

    return rval;

}

void remove_car(struct train* q, int rval)

{

	

	if(isQueueEmpty(q)==1)

	{

		printf("There is only one car on the train.\n");

		printf("---------");

		return q;

		printf("------");

	}

	

	else if(remove_car)

	{

		

		dequeue(q);

		printf("Car %d has been removed!\n", &rval);

	}

}

void expandqueue(struct train* q)

{

    int i; // used in the for loop below to copy data from old store array to new one

    int* oldstore = q->store; // pointer to the store array

    

    // now, store will point to an array that is twice the size of the old one

    q->store = calloc(q->size * 2, sizeof(int));

    

    // copy the values in the queue from the old store array to the new one

    for(i = 0; i < q->size; i++)

    {

        q->store[i] = oldstore[(i+q->front) % q->size];

    }

    q->front = 0; // the values from the old array are copied into the beginning of the new array

    q->back = q->size; // there are q->size elements in the array so that's where back will point

    q->size = q->size * 2; // the size of the store array has doubled

    free(oldstore); // always free memory that isn't being used

}
 

int add_car(struct train* q, int data)

{

    // put the new data into the back of the queue

    q->store[q->back] = data;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;
 

    // double the size of the array if we have run out of space in the current store array

    if(q->front == q->back)

    {

        expandqueue(q);

    }   

}
 

int main(void)

{

	FILE *fp;

    char fname[32];	

	int i, n;

	char action[20];

	struct station* s;

	struct train* q;

	int num_cars, rval;
 

	printf("Welcome to Bob's Train Station\n");

	printf("What is the name of the input file?\n");

	scanf("%s", fname);
 

	fp = fopen(fname, "r");

	if (fp == NULL)

		printf("ERROR");

	

	printf("Here is the output!:\n");

	

	fscanf(fp, "%d", &n);

	s=new_station(10);

	for(i=0; i<n; i++)

	{

		fscanf(fp,"%s", action);

		if(strcmp(action,"new_train")==0)

		{

			fscanf(fp, "%d", &num_cars);

			q=new_train(num_cars);				

			add_train(s, q, num_cars, fp);

		}

		else if(strcmp(action, "remove_car")==0)

		{

			remove_car(q, rval);

		}

	/*	else if(strcmp(action, "add_car")==0)

		{

			add_car(q);

		}

		else if(strcmp(action, "train_departs")==0);

		{

			place funtion here

		}//*/

	}

	fclose(fp);

		

	system("PAUSE");

	return 0;

}

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
I do not need the train departed printf's do I at all
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
That is correct.  Except that you will need one when handling the train_departs command.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
When you run the code, are you currently crashing on
                  remove_car(q, rval);
If so, that is because rval doesn't have a valid value.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
The remove_car commands in your input data don't specify which car to remove.

Also, the add_car command doesn't specify which train to add the car to.  It seems as though it should.
0
 

Author Comment

by:mikeregas
Comment Utility
this is where I am lost I am not sure the correct syntax for it. and that is where my problem is. I know that the remove  function has to call the dequeue function and isqueueempty function. I know that it is at the least an if statement. I just dont understand or know what it should be to check the isqueueempty to see if there is only one car in it then return ("There is only one car...")
0
 

Author Comment

by:mikeregas
Comment Utility
here is all the functions for the remove_car function
int isQueueEmpty(struct train* q)

{

    // if the front and back are equal to each other then the queue is empty

    return q->front == q->back;   

}

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    // Move front up one position in the store array

    // The % (modulus) operator is used to ensure that front does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->front = (q->front + 1) % q->size;

    

    // return the value that just got dequeued

    return rval;

}

void remove_car(struct train* q, int rval)

{

	

	if(isQueueEmpty(q)==1)

	{

		printf("There is only one car on the train.\n");

		printf("---------");

		return q;

		

	}

	

	else if(remove_car)

	{

		

		dequeue(q);

		printf("Car %d has been removed!\n", &rval);

	}

}

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
the code in the main is suppose to read the file then the if and else if should strcmp to find out which function to use. I have not done the add_car one yet. I am trying to get one working before I tackle the next, as the reason I am so confused

int main(void)

{

	FILE *fp;

    char fname[32];	

	int i, n;

	char action[20];

	struct station* s;

	struct train* q;

	int num_cars, rval;
 

	printf("Welcome to Bob's Train Station\n");

	printf("What is the name of the input file?\n");

	scanf("%s", fname);
 

	fp = fopen(fname, "r");

	if (fp == NULL)

		printf("ERROR");

	

	printf("Here is the output!:\n");

	

	fscanf(fp, "%d", &n);

	s=new_station(10);

	for(i=0; i<n; i++)

	{

		fscanf(fp,"%s", action);

		if(strcmp(action,"new_train")==0)

		{

			fscanf(fp, "%d", &num_cars);

			q=new_train(num_cars);				

			add_train(s, q, num_cars, fp);

		}

		else if(strcmp(action, "remove_car")==0)

		{

			remove_car(q, rval);

		}

	/*	else if(strcmp(action, "add_car")==0)

		{

			add_car(q);

		}

		else if(strcmp(action, "train_departs")==0);

		{

			place funtion here

		}//*/

	}

	fclose(fp);

		

	system("PAUSE");

	return 0;

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
OK.  One thing at a time, as you say, and we can get this handled.

Let me take the last thing you said first.

I suggest simply printing something in the else statements that you have commented out.  For example,
         else if(strcmp(action, "add_car")==0)
            {
                  printf("add_car command\n");
                  //add_car(q);
            }
            else if(strcmp(action, "train_departs")==0);
            {
                  printf("train_departs command\n");
                  //place funtion here
            }
That lets you know that the commands are being decoded correctly.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Before we can tackle remove_car, we need to verify that the arguments being passed are correct.

In the last version you posted, the rval argument isn't being read from the input data and so has an invalid value (0xcccccccc) when you call remove_car.

You could read it before calling
                  remove_car(q, rval);
or you could read in in remove_car, just like you read input data in add_train.
0
 

Author Comment

by:mikeregas
Comment Utility
here is the assignment I will just post it and you can see if it will make it easier for you to understand what I am asking or how to explain to me where I am messing up
Objective

1.  Learn how to manipulate stacks and queues in a basic fashion
 

Problem: Train Station 

Bob owns a train station at the end of a rail line.  Trains arrive and depart the station.  Also, while at the station, a train can have cars added to or removed from it.  Because Bob's station is at the end of the rail, only the last train that has arrived can leave his station, i.e., Bob's station works like a stack.  Only the last train that has entered the station can have cars added to or removed from it.  Cars are removed from the front of the train and are added to the back of the train, i.e., the trains act like queues.  Sometimes Bob's employees make mistakes and try to remove cars from trains that only have one car.  Bob does not want this to occur and wants you to write a program to ensure that this doesn't happen.
 

Your program must read in an input file describing the train schedule for the day. The input file will be a text file in the format described here. The input file will begin with a single positive integer, n, on a line by itself indicating the number of events in the schedule. On each of the next n lines is a description of an event. An event will take one of the following forms:
 

A train arrives

Train arrival events take the following form:

new_train n x1 x2 ... xn

where n is a positive integer indicating the number of cars in the new train. The numbers x1 through xn are the current cars in the train.  Car x1 is the first car and xn is the last car.  Thus, x1 will be the first car removed from this train if one were to be removed.
 

A train departs

Train departure events take the following form:

train_departs

This indicates that the last train that has entered the station will depart, and you should print out the cars that are in the train:

Train departed: x1 x2 ... xn

where n is the number of cars in the train that departed, and x1, x2, ..., xn, are the numbers of the cars in that train.  If there is no train in the station, your program should print out

Station empty, no train departed!
 

A car is detached from a train

Car detachment events take the following form:

remove_car

When this happens, you should delete the first car from the train that last entered into the station and print:

Car x removed!

where x is the number of the car that was removed.  If the train has only one car, then your program should not remove the car and instead print:

Car not removed because there is only one car on the train!

If there is no train in the station, your program should print:

Car not removed because there are no trains!
 

A car is attached to a train

Car attachment events take the following form:

add_car n

where n is an integer indicating the car number.  This new car should be added to the back of the train that last entered the station.  If there is no train in the station, your program should instead print:

Car not added because there are no trains!

Output Sample

Here is a sample output of running the program. Note that this test is NOT a comprehensive test. You should test your program with different data than is shown here based on the specifications given. You are free and even encouraged to have your output look different from the sample so long as your program obeys the problem statement. The user input is given in italics while the program output is in bold.
 

Sample input file (sample1.txt)

10

new_train 5 3 2 4 1 6

new_train 2 4 14

remove_car

remove_car

new_train 3 6 7 8

train_departs

add_car 15

train_departs

train_departs

train_departs
 

Sample Run

Welcome to Bob's train station

What is the name of the input file?

sample1.txt

Here is the output:

Car 4 removed!

Car not removed because there is only one car on the train!

Train departed: 6 7 8

Train departed: 14 15

Train departed: 3 2 4 1 6

Station empty, no train departed!
 

Output Explanation

Train #1 with cars <3,2,4,1,6> enters the station.  Then Train #2 with cars <4,14> enters in front of Train #1. Train #2 then has its #4 car removed, but doesn't have #14 removed because that is the only car left. Then, Train #3 enters in front of Train #2, and quickly leaves.  Next, car #15 is added to the back of Train #2, which then departs the station.  Next, Train #1 departs.  Finally, we try to depart a train from the station, but there aren't any left!
 

Deliverables

You must submit the source code for your programs over WebCourses by 11:55 PM on Wednesday, October 22nd, 2008.
 

Restrictions

Although you may use other compilers, your program must compile and run using Dev C++. Please use Dev C++ or another similar environment to develop your programs. Your program should include a header comment with the following information: your name, course number, assignment title, and date. Also, make sure you include comments throughout your code describing the major steps in solving the problem.

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Thank you for that.  It clarifies several questions that I had.
0
 

Author Comment

by:mikeregas
Comment Utility
>>You could read it before calling
>>                  remove_car(q, rval);
>>or you could read in in remove_car, just like you read input data in add_train.

is this what you mean:
fscanf(fname, "%d", &car);  except i think that fname needs to be fp
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
That's what I meant, but I didn't understand the assignment then and gave you the wrong suggestion.  Now I understand it better.

Removing a car is removing the first item from a queue.  The car doesn't have to be specified, just the train.

So the function prototype should look like this
   void remove_car(struct train* q)
You pass the last train that entered the station.

In the body of remove_car, where you have
      else if(remove_car)
you need to actually remove the first item (car) from the queue (train).

Once we get remove_car working right, we'll have a bigger problem to solve, but let's worry about that when the time comes.  Just pass
                  remove_car(q);
for now.
0
 

Author Comment

by:mikeregas
Comment Utility
>>In the body of remove_car, where you have
>>      else if(remove_car)
>>you need to actually remove the first item (car) from the queue (train).
I do this with some kind of a loop? or am I writing another function
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
You already have
   int dequeue(struct train* q)
which appears to be coded correctly.

Just use that.
0
 

Author Comment

by:mikeregas
Comment Utility
dequeue(q);//I called the function
            printf("Car %d has been removed!\n", rval);//this pulls its value?
void remove_car(struct train* q)

{

	int rval;

	//fscanf(fp, "%d");
 

	if(isQueueEmpty(q)==1)

	{

		printf("There is only one car on the train.\n");

		printf("---------");

		return q;

		

	}

	

	else if(remove_car)

	{

		

		dequeue(q);

		printf("Car %d has been removed!\n", rval);

	}

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Well, almost.  I was thinking
void remove_car(struct train* q)
{
      
      if(isQueueEmpty(q)==1)
      {
            printf("There is only one car on the train.\n");
            printf("---------");
            //return q;
            printf("------");
      }
      else
      {
            int rval = dequeue(q);
            printf("Car %d has been removed!\n", &rval);
      }
}

dequeue isn't quite right.  Give me a minute.
0
 

Author Comment

by:mikeregas
Comment Utility
Take your time, you are explaining this better than the guys in the computer lab did all day!
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Thank you!

Here's the real problem.  The code can't tell the difference between a full queue and an empty queue.  Let me explain.

When you initially set up the queue (train), it has 0 cars and the front and back offsets are both 0.  When you add cars in add_train, the line
        q->back = (q->back + 1) % q->size;
increments in size as you add cars...
   car 1, q->back = 1
   car 2, q->back = 2
   car 3, q->back =3
   car 4, q->back =4
   car 5, q->back =5
except that the line has the modulus operator in it
   % q->size
where
   q->size == 5
so
   q->back =5
but the result of 5 % 5 is zero.
So
   car 5, q->back =0
is the actual result.

Is that making sense to you?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Here is a solution to that problem
http://www.soe.ucsc.edu/classes/cmps012b/Spring97/Lecture07/tsld011.htm

(I googled for
   full empty queue
0
 

Author Comment

by:mikeregas
Comment Utility
yes so the queue needs to be expanded when it gets full?
0
 

Author Comment

by:mikeregas
Comment Utility
doesnt this make the queue bigger when it needs to be bigger?
void expandqueue(struct train* q)

{

    int i; // used in the for loop below to copy data from old store array to new one

    int* oldstore = q->store; // pointer to the store array

    

    // now, store will point to an array that is twice the size of the old one

    q->store = calloc(q->size * 2, sizeof(int));

    

    // copy the values in the queue from the old store array to the new one

    for(i = 0; i < q->size; i++)

    {

        q->store[i] = oldstore[(i+q->front) % q->size];

    }

    q->front = 0; // the values from the old array are copied into the beginning of the new array

    q->back = q->size; // there are q->size elements in the array so that's where back will point

    q->size = q->size * 2; // the size of the store array has doubled

    free(oldstore); // always free memory that isn't being used

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Only in one case -- where the train has arrived, no cars have been removed from it, and a car is being added.

The assignment says "You should test your program with different data than is shown here based on the specifications given. "  So we should probably cover this case.

A really simple way to cover this case is to simply say that the car can't be added.  At least that way you've handled the situation.  There is no requirement given that you actually comply with the command.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>doesnt this make the queue bigger when it needs to be bigger?
Yes, it seems to.  Just reading the code, it looks good to me.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
add_car will need to check the queue and call expand_queue if the queue is currently full.
0
 

Author Comment

by:mikeregas
Comment Utility
you are saying that it cant be added becaause there is not another train to added it to, or you just cant add past x number of cars
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>add_car will need to check the queue and call expand_queue if the queue is currently full.
I see that it does.  It should check the queue size *before* trying to add anything to the queue.

So the check should move from the end of add_car to the beginning of add_car.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>So the check should move from the end of add_car to the beginning of add_car.
Yes

0
 

Author Comment

by:mikeregas
Comment Utility
so that function (expandqueue(q)) needs to be added to both add_car and remove_car?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
I will need to go to bed in a half hour or so.
0
 

Author Comment

by:mikeregas
Comment Utility
this is what you are saying that it needs to check before the function actually runs to see if it needs to make more room.
void remove_car(struct train* q)

{

	int rval;

	//fscanf(fp, "%d");
 

	 if(q->front == q->back)

    {

        expandqueue(q);

    }

	if(isQueueEmpty(q)==0)

	{

		printf("There is only one car on the train.\n");

		//printf("---------");

		return q;

		

	}

	

	else if(remove_car)

	{

		

		int rval=dequeue(q);

		printf("Car %d has been removed!\n", rval);

	}

}
 

int add_car(struct train* q, int data)

{

     if(q->front == q->back)

    {

        expandqueue(q);// double the size of the array if we have run out of space in the current store array

    }

	// put the new data into the back of the queue

    q->store[q->back] = data;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;
 

    

      

}

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
that is good I will need to do the same, I will be working on this tomorrow so I only loose 10 points if I can get it figured out by midnight tomorrow
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
No, I was talking about add_car.  It needs to make this check because it could be asked to add a car to a queue that is already full.

For remove_car, the problem is that is can't tell an empty queue from a full queue, since both case have
   q->front == q->back
There is no need to expand the queue when removing a car, because removing a car makes the queue shorter.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>I will be working on this tomorrow
I should be available around 6PM Pacific time.  I'll be glad to help you then.

And I'm OK until 10PM Pacific tonight.
0
 

Author Comment

by:mikeregas
Comment Utility
so I have taken it out of remove_car and added it to add_car, am I in the right direction?

 if(q->front == q->back)
    {
        expandqueue(q);
    }
      
0
 

Author Comment

by:mikeregas
Comment Utility
sounds good another half an hour and I think my computer might be asking to go for a swim if I have to look at it any longer
lol
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Yes, you are.

How do you plan to differentiate between a full and an empty queue?

Earlier I posted
Here is a solution to that problem
http://www.soe.ucsc.edu/classes/cmps012b/Spring97/Lecture07/tsld011.htm

(I googled for
   full empty queue
0
 

Author Comment

by:mikeregas
Comment Utility
when I run the program it seems to be doing what is asked for with the output for the remove car function, although the rest is still left. it is going through the if statements and prints out add_car which if the function was being called should be working. the train departs is everywhere though
0
 

Author Comment

by:mikeregas
Comment Utility
isnt that where this part of the code compairs the two parts of the queue q->front == q->back
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>the train departs is everywhere though
Do you still have
   printf("Train Departed: ");
in add_train?

Would you post your code again, so that I can be sure I'm tracking with you?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>isnt that where this part of the code compairs the two parts of the queue q->front == q->back

Well yes, but
   q->front == q->back
is true for both an empty queue and a full queue.
0
 

Author Comment

by:mikeregas
Comment Utility
I think I am up in the air on this one, I understand that it needs to expand if needed. I thought that is what the expandqueue does, but I am also thinking that this is what I really need:
Method 3: always keep at least one queue entry unused. Then an empty queue has condition (rear+1)%MAX == front , while a full queue has condition (rear+2)%MAX == front
0
 

Author Comment

by:mikeregas
Comment Utility
>>Do you still have
   printf("Train Departed: ");
in add_train?

it is coming from: else if(strcmp(action, "train_departs")==0);
0
 

Author Comment

by:mikeregas
Comment Utility
>>isnt that where this part of the code compairs the two parts of the queue q->front == q->back

Well yes, but
   q->front == q->back
is true for both an empty queue and a full queue.

but I dont think that it is possible to actually have an empty queue is it, because there always has to be a car on the train.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>it is coming from: else if(strcmp(action, "train_departs")==0);
Remove the semicolon from the end of the line
0
 

Author Comment

by:mikeregas
Comment Utility
damn I feel stupid for not seeing that
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Method 3 works for me.

Here's how I would approach the problem.  Have add_train call add_car to add a car, rather than doing it in the loop you have now.  Have add_car check the queue to see whether it is full and call expandqueue if necessary.

When add_train is called, q->front == q->back because both are zero.  Let's define that as an empty queue.

So on add_train's first call to add_car, add_car determines that there is no more room in the queue and so calls expandqueue.  There are two conditions for no more room:
1)  q->front == q->back because both are zero
2)  There is only one empty slot in the queue, and method 3 says there must always be one empty.  You'll be filling that empty slot when you add the car, so one empty slot isn't enough.  
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Its getting time to shut it down.  You need some sleep and so do I.

Don't feel stupid.  I can't count the number of time in almost 40 years of experience that I haven't seen something that is totally obvious.

(That's why a programmer can never do a good job of reviewing his own code.  Almost anyone else can do a better job.)
0
 

Author Comment

by:mikeregas
Comment Utility
I put the expandqueue in the add_car function and I commented on where I thought the add_car should go int he add_train function
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;
 

	//printf("Train Departed: ");

    //here is where I would placce the add_car function

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		//printf("%d ", car);

        q->store[q->back] = car;

        q->back = (q->back + 1) % q->size;

        //expand queue check

    }

//printf("\n");
 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}
 

int add_car(struct train* q, int data)

{

     if(q->front == q->back)

    {

        expandqueue(q);// double the size of the array if we have run out of space in the current store array

    }

	// put the new data into the back of the queue

    q->store[q->back] = data;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;
 

    

      

}

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
sounds good, I am just wondering what is the best way to learn this stuff so that it makes more since, I do not like the way that it is being taught where we only have one assignment that uses all the info that we have learned for the past couple of weeks I would think that several smaller assignments would be more binificial than one big one that is confusing to a beginner
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Yes, I agree.  Instead of
       q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
you'll add something like
     add_car(q,car);

That's about it for me tonight.  See you tomorrow, eh?
0
 

Author Comment

by:mikeregas
Comment Utility
yes thank you and I will be here tomorrow. Thanks again and have a good night
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>several smaller assignments would be more binificial
I *totally* agree with that.  The best way to teach someone is to bring them along in a gradual fashion, giving them success after success until they are confident they know what they are doing.

A single tough assignment does not do that and is poor teaching, in my book.

One thing you can do is to write a small program for each new concept or new section.  Make up a simple problem and solve it.  You'll be confident by the time the tough assignment comes around.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Good night.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Why don't you post your current code sometime shortly before 6PM Pacific, so that we start off in sync.

Good night.

Joe
0
 

Author Comment

by:mikeregas
Comment Utility
sounds good, I will post something around 5 when I get off work and we will go from there.
Thanks again...

Mike
0
 

Author Comment

by:mikeregas
Comment Utility
Here is what I have done so far. It is not a lot, but it is something. I did something were the remove car function is not working properly. It does not return the value of the car that is being removed. in the add_car function I am trying to get it to read the car that is added but I think that I have put more info in it then is needed.

bye the way I hope that you have had a good day. and once again thanks


/*George Regas

  COP 3502

  g0616085

  Oct 22, 2008

  Assignment 3:

  Bob's Train Station

*/

#include <stdio.h>
 

struct station* new_station(int initial_Size);

struct train* new_train(int initial_size);	

void print_stack(struct station* s);

void print_queue(struct train* q);

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);

int last_car(struct queue* q);

int isQueueEmpty(struct train* q);
 

struct train

{

    int* store;

    int front;

    int back;

    int size;

};
 

struct station

{

    struct train * store;

    int top;

    int size;

};
 

struct station* new_station(int initial_Size) //my stack

{

    struct station* s;

    

    s = malloc(sizeof(struct station));

    

    s->store = calloc(initial_Size, sizeof(struct train));

    s->top = 0;

    s->size = initial_Size;

    

    return s;

}
 

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;
 

	//printf("Train Departed: ");
 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		//printf("%d ", car);

        q->store[q->back] = car;

        q->back = (q->back + 1) % q->size;

        //expand queue check

    }

//printf("\n");
 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}
 

struct train* new_train(int initial_size) //my queue

{

    struct train* q;

    

    q = malloc(sizeof(struct train));

    q->store = calloc(initial_size, sizeof(int));

    q->front = 0;

    q->back = 0;

    q->size = initial_size;

    

    return q;   

}
 

void print_queue(struct train* q)

{

	int i;

	

	for(i=q->front; i < q->back; i++)

		printf("%d", q->store[i]);
 

}

void print_stack(struct station* s)

{

    int i; // index used in for loop

    

    // loop through stack from top to bottom, printing them out as we go

    for(i = 0; i < s->top; i++)

        print_queue;

       

}

// This function returns true if the queue is empty and false otherwise

int isQueueEmpty(struct train* q)

{

    // if the front and back are equal to each other then the queue is empty

    return q->front == q->back;   

}

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    // Move front up one position in the store array

    // The % (modulus) operator is used to ensure that front does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->front = (q->front + 1) % q->size;

    

    // return the value that just got dequeued

    return rval;

}

void remove_car(struct train* q)

{

	int rval;

	//fscanf(fp, "%d");

 

	 

	if(isQueueEmpty(q)==0)

	{

		printf("There is only one car on the train.\n");

		return q;

		

	}

	

	else if(remove_car)

	{

		

		int rval=dequeue(q);

		printf("Car %d has been removed!\n", q);

	}

}
 

void expandqueue(struct train* q)

{

    int i; // used in the for loop below to copy data from old store array to new one

    int* oldstore = q->store; // pointer to the store array

    

    // now, store will point to an array that is twice the size of the old one

    q->store = calloc(q->size * 2, sizeof(int));

    

    // copy the values in the queue from the old store array to the new one

    for(i = 0; i < q->size; i++)

    {

        q->store[i] = oldstore[(i+q->front) % q->size];

    }

    q->front = 0; // the values from the old array are copied into the beginning of the new array

    q->back = q->size; // there are q->size elements in the array so that's where back will point

    q->size = q->size * 2; // the size of the store array has doubled

    free(oldstore); // always free memory that isn't being used

}
 

int add_car(struct train* q)

{

    int data;

		

	if(q->front == q->back)

    {

        expandqueue(q);

    }  

	// put the new data into the back of the queue

    q->store[q->back] = data;

		int data = add_car(q);

		return q;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;

		

    // double the size of the array if we have run out of space in the current store array

     

}
 

int main(void)

{

	FILE *fp;

    char fname[32];	

	int i, n;

	char action[20];

	struct station* s;

	struct train* q;

	int num_cars, rval, data;
 

	printf("Welcome to Bob's Train Station\n");

	printf("What is the name of the input file?\n");

	scanf("%s", fname);
 

	fp = fopen(fname, "r");

	if (fp == NULL)

		printf("ERROR");

	

	printf("Here is the output!:\n");

	

	fscanf(fp, "%d", &n);

	s=new_station(10);

	for(i=0; i<n; i++)

	{

		fscanf(fp,"%s", action);

		if(strcmp(action,"new_train")==0)

		{

			//printf("******");

			fscanf(fp, "%d", &num_cars);

			q=new_train(num_cars);				

			add_train(s, q, num_cars, fp);

		}

		else if(strcmp(action, "remove_car")==0)

		{

			//printf("---------");

			remove_car(q);

		}

		else if(strcmp(action, "add_car")==0)

		{

			printf("add_car\n");

			add_car(q);

		}

		else if(strcmp(action, "train_departs")==0)

		{

			printf("Train Departed:\n");

			//place funtion here

		}

	}

	fclose(fp);

		

	system("PAUSE");

	return 0;

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Hi, I'm here now.  Thank you, yes, I had an excellent day.  I hope you did also.

I'll take a look at the code and be with you shortly.

And you're very welcome!
0
 

Author Comment

by:mikeregas
Comment Utility
I have to run to the store for my pregnant wife and get her some food, I should be back within 30 minutes
thank you
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
A couple of comments...In remove_car, please remove the int rval at
void remove_car(struct train* q)
{
      int rval;
because the variable is never used.  The line
            int rval=dequeue(q);
defines rval a second time and this definition hides the other.  The second rval definition is good style because it defines the variable as close to its usage as possible, making it easy to find.

In add_car, there are two definitions of
   int data;
The second one is in error, because in C you can't define variables following code within a brace.

The remove_car second definition of rval has an open brace at
      else if(remove_car)
      {
so the second of rval appears within its scope (its brace) before any code.  That makes it OK.

This is just some minor cleanup and isn't intended to answer your question.  I'll do that shortly.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>have to run to the store
No problem, man.  Take good care of her!

The problem with remove_car is really a problem with isQueueEmpty.  isQueueEmpty is typed int.  You're really returning a bool because the expression
   q->front == q->back
is a boolean (due to the == operator).

On the first call to remove car, the queue is empty (q->front == q->back == 0), so the comparison returns true, which is given the value of 1 (one).

Therefore the
   if(isQueueEmpty(q)==0)
in remove_car operates backward from what you want.

Changing it to
   if(isQueueEmpty(q))
fixes that problem.

Next, the "if (remove_car) in
      else if(remove_car)
is always true because remove_car is always non-zero -- it is the address of a function.

That means you don't need it and should remove it.

Last, you don't want to print the train in
            printf("Car %d has been removed!\n", q);
you want to print the car.

Making all those changes, you get
void remove_car(struct train* q)
{
      if(isQueueEmpty(q))
      {
            printf("There is only one car on the train.\n");
            //return q;
      }
      else
      {
            int rval=dequeue(q);
            printf("Car %d has been removed!\n", rval);
      }
}

The program still won't run right...There is another, bigger, problem as I mentioned last night.

Tell me whether this makes sense to you and then we'll go on to the next step.
0
 

Author Comment

by:mikeregas
Comment Utility
ok I am back, taco bell. LOL she eat off the wall stuff right now

I do understand what you are saying and I made the change that you mentioned
0
 

Author Comment

by:mikeregas
Comment Utility
>>Changing it to
   if(isQueueEmpty(q))
fixes that problem.

Does this still address the fact that there can not be a train with 0 cars
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Yes.  Now an empty train is recognized correctly.
0
 

Author Comment

by:mikeregas
Comment Utility
in the add_car function I think that I have addressed it below properly. take a look and let me know if I am going in the right direction
int add_car(struct train* q)

{

    int data;

		

	if(q->front == q->back)

    {

        expandqueue(q);

    }  

	// put the new data into the back of the queue

    q->store[q->back] = q;

		//int data = add_car(q);

		return q;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;

		

    // double the size of the array if we have run out of space in the current store array

     

}

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
I am not sure what I removed from last nights code today it is not returning the proper car in this line:

printf("Car %d has been removed!\n", rval);
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
The statement
      if(q->front == q->back)
is the same as
      if(isQueueEmpty(q))
So you're saying "When I add a car, if the queue is empty, then expand the queue".

That doesn't make sense, does it?
0
 

Author Comment

by:mikeregas
Comment Utility
no it doesnt, I am jsut repeating myself here. right?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Let's do one thing at a time.

The problem I'm seeing is that the train always has zero cars...this is my output
Welcome to Bob's Train Station
What is the name of the input file?
Here is the output!:
There is only one car on the train.
There is only one car on the train.
Train Departed:
add_car

Are we in sync?
0
 

Author Comment

by:mikeregas
Comment Utility
actually I need to read the queue first then determine if I need to expand  the queue
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>I am jsut repeating myself here. right?
Well, no.  The statement just doesn't make sense.

Let's get in sync.  I'll wait for you to respond to my last question.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:mikeregas
Comment Utility
yes, lets get remove_car and then work on next thing
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
All right.  The problem I am seeing is that the train is always empty.  

So before fixing remove_car, we need to fix adding cars to the train so that we have cars to remove.

The first train is created by processing this command
   new_train 5 3 2 4 1 6
So we have to fix add_train.

add_train adds a car and then increments the back pointer with
        q->back = (q->back + 1) % q->size;
I mentioned last night that the modulus operator is causing the back pointer to wrap back to zero.

(more coming)
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
What we need to do is to have add_train call add_car to add the car.  i'm saying that instead of
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
we define add_car to take a train and a car and then add the car to the train.

Something like
   int add_car(struct train* q, int car)

So we replace the add_train lines above with
   add_card(q,car);

We'll need to modify all add_car calls to conform to the new signature and fix add_car so that it works right.

Make sense so far?
0
 

Author Comment

by:mikeregas
Comment Utility
so instead of you the % I should be adding 1 to the queue everytime a car is added?
0
 

Author Comment

by:mikeregas
Comment Utility
it does so far I am just a little lost with the add_car(q,car);

I know what you are saying, so it should look like this
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;
 

	//printf("Train Departed: ");
 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		//printf("%d ", car);

         add_card(q,car);

         add_card(q,car);

        //expand queue check

    }

//printf("\n");
 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
I'm thinking that there are three situations:
1)  In add_train, the size is defined but q->store has no space allocated.  So add_train needs to allocate space for q->store.
2)  In add_car, the queue may be full.  In that case, the queue needs to be expanded.
3)  In add_car, the queue may not be full.  In that case just add the car to the queue.

So far, so good?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>add_card(q,car);
>>add_card(q,car);

Only need one of these
add_car(q,car);

Otherwise, yes, that's what I'm saying as far as replacing the
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
goes.

0
 

Author Comment

by:mikeregas
Comment Utility
i understand that, makes good sense
0
 

Author Comment

by:mikeregas
Comment Utility
>>
Only need one of these
add_car(q,car);

Otherwise, yes, that's what I'm saying as far as replacing the
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
goes.

I thought that it looked a littel out of place calling the same function twice.
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;

 

	//printf("Train Departed: ");

 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		//printf("%d ", car);

         add_card(q,car);

        //expand queue check

    }

//printf("\n");

 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
That looks OK, except that you have a 'd' at the end of add_car.  The way you have it, it won't compile.  Need add_car instead of add_card.

OK, so then, what to do with add_car?

First off, the lines
      if(q->front == q->back)
    {
        expandqueue(q);
    }  
don't make sense here and need to be replaced.

What we really want to know is: Is there more than one empty place in the queue?  If so, we can just add this car and increment the back point.  If not, we need to expand the queue.

I'm thinking we need a function
   int IsThereAtLeastOneEmptySlotInTheQueue(q)
and then write something like

      if(!IsThereAtLeastOneEmptySlotInTheQueue(q)) // notice the ! symbol
    {
        expandqueue(q);
    }  

Do you feel up to writing that function?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Actually, given that you're doing Method three, that should be
   AreThereAtLeastTwoEmptySlotsInTheQueue(q)
0
 

Author Comment

by:mikeregas
Comment Utility
yes I can give it a try and you tell me where I am worng
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
0
 

Author Comment

by:mikeregas
Comment Utility
so all that it is doing is checking to see if there are two empty spaces at the back of the quque

int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q)
{
      if(!IsThereAtLeastTwoEmptySlotInTheQueue(q))
      {
            expandqueue(q);
      }
}
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
As written in that message, the function will recur until the stack is exhausted.

Did you mean to say that this is the add_car function, as in
int add_car(struct train* q)
{
      if(!IsThereAtLeastTwoEmptySlotInTheQueue(q))
      {
            expandqueue(q);
      }
}
0
 

Author Comment

by:mikeregas
Comment Utility
I actually need something to read the queue and determine what is left on the end

this is actually where I am confused I need to read add_train and see if there are two cars at the end:
add_car(q)= add_car+2
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
I suggest that the simplest solution is to keep a count variable in the train struct.  Have add_car increment the count and have remove_car decrement the count.

Then IsThereAtLeastTwoEmptySlotInTheQueue becomes a simple comparison of the queue size to the count.
0
 

Author Comment

by:mikeregas
Comment Utility
is this a litle better looking ?

int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q)
{
      int i;

      for(i=add_car; i < add_car; i+2)

      if(!IsThereAtLeastTwoEmptySlotInTheQueue(q))
      {
            expandqueue(q);
      }
}
0
 

Author Comment

by:mikeregas
Comment Utility
there is an error with this part here and  I think that I am going in the right direction:

int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q)
{
      int i;

      for(i=add_car(q); i < add_car(q); i+2)

      if(!IsThereAtLeastTwoEmptySlotInTheQueue(q))
      {
            expandqueue(q);//this is where the error is redefinition; different basic types
      }
}
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Sorry I had a call.  Give me just a moment
0
 

Author Comment

by:mikeregas
Comment Utility
no problem
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Here's code that expresses what I am trying to say

Add a count variable to the train struct
struct train
{
    int* store;
    int front;
    int back;
    int count; // Number of items in the queue
    int size;
};

Have dequeue decrement that count because one less car is on the train
int dequeue(struct train* q)
{
...code as you have it now
    q->front = (q->front + 1) % q->size;
    q->count--;  // this is the new line

Check the queue size against the number of cars on the train
int AreThereAtLeastTwoEmptySlotsInTheQueue(struct train* q) {
   return (q->size - q->count) >= 2;
}

Have add_car add one to the count because there is now one more car on the train
int add_car(struct train* q, int car)
{
    //int data;
            
      if(!AreThereAtLeastTwoEmptySlotsInTheQueue(q))
    {
        expandqueue(q);
    }  
      // put the new data into the back of the queue
    q->store[q->back] = car;
    ...need to increment the back pointer here
        q->count++;

Does that make sense?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
I forgot to mention that add_train needs to initialize the count
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
      //printf("Train Departed: ");
   q->count = 0;
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Now IsQueueEmpty becomes very simple
int isQueueEmpty(struct train* q)
{
    return q->count == 0;  
}
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Actually, since all trains must have at least one car, isQueueEmpty needs to be modified slightly.

Can you see your way clear to making that change?
0
 

Author Comment

by:mikeregas
Comment Utility
I understand what you are saying all the way up to the add_car:
    q->store[q->back] = car;

int add_car(struct train* q, int car)

{

    //int data;

		

	if(!AreThereAtLeastTwoEmptySlotsInTheQueue(q))

    {

        expandqueue(q);

    }    

	// put the new data into the back of the queue

    q->store[q->back] = car;

	q->count++;

		//int data = add_car(q);

		return q;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;

		

    // double the size of the array if we have run out of space in the current store array

     if(isQueueEmpty(q))

    {

        expandqueue(q);

    }

}
 

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    // Move front up one position in the store array

    // The % (modulus) operator is used to ensure that front does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->front = (q->front + 1) % q->size;

    

    // return the value that just got dequeued

    return rval;
 

		q->front = (q->front + 1) % q->size;

		q->count--;  // this is the new line

}
 

int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q)

{

	return (q->size - q->count) >= 2;

}

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
Now IsQueueEmpty becomes very simple
int isQueueEmpty(struct train* q)
{
    return q->count == 0;  
}
Can you see your way clear to making that change?

needs to equal 3, one for the car that has to be there and two for the empty places in the queue
0
 

Author Comment

by:mikeregas
Comment Utility
needs to equal 3, one for the car that has to be there and two for the empty places in the queue
return q->count == 3;

also when I compile it I get an error that car is an udelclaired identifier in the main

add_car(q, car);
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>I understand what you are saying all the way up to the add_car:
>>    q->store[q->back] = car;

The
    q->store[q->back] = car;
is your code, so I'm guessing you're confused by the
    ...need to increment the back pointer here
statement.  I was mistaken.  You are already incrementing the back pointer with
    q->back = (q->back + 1) % q->size;
so you can ignore my
    ...need to increment the back pointer here
statement.

>>needs to equal 3, one for the car that has to be there and two for the empty places in the queue
Almost right.  The reason we're saying there have to be two empty places is that we need one empty place after adding the car.  So "needs to equal 2" would be correct.

Does that make sense?
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>car is an udelclaired identifier in the main
You need an car definition
      int car;
and then
            else if(strcmp(action, "add_car")==0)
            {
                  //printf("add_car\n");
         fscanf(fp, "%d", &car);
                  add_car(q,car);
            }
0
 

Author Comment

by:mikeregas
Comment Utility
this is what i got when I compiled and I made all the changes that you suggested:

1>train2.obj : error LNK2019: unresolved external symbol _add_card referenced in function _add_train
1>train2.obj : error LNK2019: unresolved external symbol _AreThereAtLeastTwoEmptySlotsInTheQueue referenced in function _add_car
1>C:\Users\Mike Regas\Documents\COP3205\Program Assignments\train2\Debug\train2.exe : fatal error LNK1120: 2 unresolved externals
1>Build log was saved at "file://c:\Users\Mike Regas\Documents\COP3205\Program Assignments\train2\train2\Debug\BuildLog.htm"
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>unresolved external symbol _add_card referenced in function _add_train
You need a function prototype (place it with your other function prototypes)
int add_car(struct train* q, int car);

>>unresolved external symbol _AreThereAtLeastTwoEmptySlotsInTheQueue referenced in function _add_car
AreThereAtLeastTwoEmptySlotsInTheQueue needs to be defined earlier in the file than add_car
Alternatively, you can add a function prototype for it.
0
 

Author Comment

by:mikeregas
Comment Utility
I added the prototypes and it gave me the same errors. I have attached my program code so maybe you can see where my error is.
/*George Regas

  COP 3502

  g0616085

  Oct 22, 2008

  Assignment 3:

  Bob's Train Station

*/

#include <stdio.h>
 

struct station* new_station(int initial_Size);

struct train* new_train(int initial_size);	

void print_stack(struct station* s);

void print_queue(struct train* q);

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);

int last_car(struct queue* q);

int isQueueEmpty(struct train* q);

int add_car(struct train* q, int car);

int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q);
 

struct train

{

    int* store;

    int front;

    int back;

	int count;//number of cars in queue

    int size;

};
 

struct station

{

    struct train * store;

    int top;

    int size;

};
 

struct station* new_station(int initial_Size) //my stack

{

    struct station* s;

    

    s = malloc(sizeof(struct station));

    

    s->store = calloc(initial_Size, sizeof(struct train));

    s->top = 0;

    s->size = initial_Size;

    

    return s;

}
 

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;

 

	//printf("Train Departed: ");

	q->count = 0;
 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		//printf("%d ", car);

         add_card(q,car);

        //expand queue check

    }

//printf("\n");

 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}
 

int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q)

{

	return (q->size - q->count) >= 2;

}

struct train* new_train(int initial_size) //my queue

{

    struct train* q;

    

    q = malloc(sizeof(struct train));

    q->store = calloc(initial_size, sizeof(int));

    q->front = 0;

    q->back = 0;

    q->size = initial_size;

    

    return q;   

}
 

void print_queue(struct train* q)

{

	int i;

	

	for(i=q->front; i < q->back; i++)

		printf("%d", q->store[i]);
 

}

/*void print_stack(struct station* s)

{

    int i; // index used in for loop

    

    // loop through stack from top to bottom, printing them out as we go

    for(i = 0; i < s->top; i++)

        print_queue;

       

}*/

int isQueueEmpty(struct train* q)// checks to see if the queue is empty

{

	return q->count == 2;//because the queue has to have 3 space in it at a minimium

}

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    

  

    q->front = (q->front + 1) % q->size;// Move front up one position in the store array

    

    

    return rval;// return the value that just got dequeued
 

		q->front = (q->front + 1) % q->size;

		q->count--;  // this is the new line

}

void remove_car(struct train* q)//removes car from the train   

{

      if(isQueueEmpty(q))//checks to see if there are enough cars to allow the car to be removed

      {

            printf("There is only one car on the train.\n");

            

      }

      else

      {

            int rval=dequeue(q);//returns the value of the car removed

            printf("Car %d has been removed!\n", rval);

      }

}
 
 

void expandqueue(struct train* q)

{

    int i; // used in the for loop below to copy data from old store array to new one

    int* oldstore = q->store; // pointer to the store array

    

    // now, store will point to an array that is twice the size of the old one

    q->store = calloc(q->size * 2, sizeof(int));

    

    // copy the values in the queue from the old store array to the new one

    for(i = 0; i < q->size; i++)

    {

        q->store[i] = oldstore[(i+q->front) % q->size];

    }

    q->front = 0; // the values from the old array are copied into the beginning of the new array

    q->back = q->size; // there are q->size elements in the array so that's where back will point

    q->size = q->size * 2; // the size of the store array has doubled

    free(oldstore); // always free memory that isn't being used

}
 

int add_car(struct train* q, int car)

{

    //int data;

		

	if(!AreThereAtLeastTwoEmptySlotsInTheQueue(q))

    {

        expandqueue(q);

    }    

	// put the new data into the back of the queue

    q->store[q->back] = car;

	

		//int data = add_car(q);

		return q;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;

		

    // double the size of the array if we have run out of space in the current store array

     if(isQueueEmpty(q))

    {

        expandqueue(q);

    }

}
 

int main(void)

{

	FILE *fp;

    char fname[32];	

	int i, n;

	char action[20];

	struct station* s;

	struct train* q;

	int num_cars, rval, data, car;

	
 

	printf("Welcome to Bob's Train Station\n");

	printf("What is the name of the input file?\n");

	scanf("%s", fname);
 

	fp = fopen(fname, "r");

	if (fp == NULL)

		printf("ERROR");

	

	printf("Here is the output!:\n");

	

	fscanf(fp, "%d", &n);

	s=new_station(10);

	for(i=0; i<n; i++)

	{

		fscanf(fp,"%s", action);

		if(strcmp(action,"new_train")==0)

		{

			//printf("******");

			fscanf(fp, "%d", &num_cars);

			q=new_train(num_cars);				

			add_train(s, q, num_cars, fp);

		}

		else if(strcmp(action, "remove_car")==0)

		{

			//printf("---------");

			remove_car(q);

		}

		else if(strcmp(action, "add_car")==0)

		{

			//printf("add_car\n");

			fscanf(fp, "%d", &car);

			add_car(q, car);

		}

		else if(strcmp(action, "train_departs")==0)

		{

			printf("Train Departed:\n");

			//place funtion here

		}

	}

	fclose(fp);

		

	system("PAUSE");

	return 0;

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
In add_train, the code calls
         add_card(q,car);
Remove the trailing 'd' from add_card, making it add_car.

In add_car, the code calls
      if(!AreThereAtLeastTwoEmptySlotsInTheQueue(q))
I used AreThereAtLeastTwoEmptySlotsInTheQueue in my example, you used IsThereAtLeastTwoEmptySlotInTheQueue

With those two changes, the code compiles.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Right now, add_car has a
   return q;
in the middle of the function.  It needs to move to the end of the function.

Also, the code
     //double the size of the array if we have run out of space in the current store array
     if(isQueueEmpty(q))
    {
        expandqueue(q);
    }
is left over from the previous version, before we added
      if(!IsThereAtLeastTwoEmptySlotInTheQueue(q))
    {
        expandqueue(q);
    }    

Please delete the
     //double the size of the array if we have run out of space in the current store array
     if(isQueueEmpty(q))
    {
        expandqueue(q);
    }

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Right now, I'm getting this for output.  Are you getting the same?

Welcome to Bob's Train Station
What is the name of the input file?
Here is the output!:
Car 4 has been removed!
Car 14 has been removed!
Train Departed:
Train Departed:
Train Departed:
Train Departed:
Press any key to continue . . .
0
 

Author Comment

by:mikeregas
Comment Utility
thankyou, I do not understand what there error messages mean and it makes it very difficult to fix them

Now I guess poping the stack is next
0
 

Author Comment

by:mikeregas
Comment Utility
this is what I am getting and I know it is wrong, I know that I have something vry small that is making read the queue wrong, or at least that is what I think it should be doing

Welcome to Bob's Train Station
What is the name of the input file?
Here is the output!:
Car 14 has been removed!
Car 0 has been removed!
Train Departed:
Train Departed:
Train Departed:
Train Departed:
Press any key to continue . . .
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
How does your add_car compare to this?  That should be where the problem is.

int add_car(struct train* q, int car)
{
    //int data;
            
      if(!IsThereAtLeastTwoEmptySlotInTheQueue(q))
    {
        expandqueue(q);
    }    
      // put the new data into the back of the queue
    q->store[q->back] = car;
      
            //int data = add_car(q);
            //return q;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
            
    return q;
}
0
 

Author Comment

by:mikeregas
Comment Utility
I had the isQueueEmpty at the end
0
 

Author Comment

by:mikeregas
Comment Utility
allthough looking at the example the 14 car should not be removed
0
 

Author Comment

by:mikeregas
Comment Utility
so it is looping through the last queue right
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Fixing this requires three changes...add_car and dequeue needs to update the count to reflect the state of the queue after they have made their respective changes to the queue.  isQueueEmpty needs to return true if there is only one car on the train.

add_car needs a
    q->count++;

dequeue needs a
    q->count--;

And finally the queue is empty if there is only one car, so isQueueEmpty needs
return q->count < 2;

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>so it is looping through the last queue right
Yes.  This is progress.
0
 

Author Comment

by:mikeregas
Comment Utility
sweet! I think the end is near. The only thing left is to pop the stack, and pprint the queue

this is what I have for printing so far

/*void print_stack(struct station* s)

{

    int i; // index used in for loop

    

    // loop through stack from top to bottom, printing them out as we go

    for(i = 0; i < s->top; i++)

        print_queue;

       

}*/

Open in new window

0
 

Author Comment

by:mikeregas
Comment Utility
that means that I need to combine the print queue and printstack
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Instead of
        print_queue;
you want
        print_queue(s->store);
I believe

You also probably want print_stack to print out a train number before calling print_queue and to print a newline after calling print_queue.

That looks like it will work.

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
>>You also probably want print_stack to print out a train number before calling print_queue and to print a newline after calling print_queue.

Sorry, my mistake on that.  I'm looking at the code again.
0
 

Author Comment

by:mikeregas
Comment Utility
my output looks something like this

Here is the output:!
3 2 4 1 6 14 Car 4 has been removed!
There is only one car on the train.
6 7 8 324106
324106
324106
Train Departed:
324106
324106
324106
Train Departed:
324106
324106
324106
Train Departed:
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Yes.  There are two problems.

First, with respect to the 324106, which should be 32416, the problem is in expandqueue.  These three lines
    q->front = 0; // the values from the old array are copied into the beginning of the new array
    q->back = q->size; // there are q->size elements in the array so that's where back will point
    q->size = q->size * 2; // the size of the store array has doubled
are not necessary, since we aren't changing the contents of the queue, just making it longer.  All three lines need to be removed.

In particular, the
    q->back = q->size; // there are q->size elements in the array so that's where back will point
changes the value of q->back, and that is why the 0 gets inserted.

I talk about the other problem shortly.

Would you make this change, show that you now print 32416, and then post your code?
0
 

Author Comment

by:mikeregas
Comment Utility
my output does not have the 32416 in it?

Here is the output:!
3 2 4 1 6 14 Car 4 has been removed!
There is only one car on the train.
6 7 8 Train Departed:
Train Departed:
Train Departed:
Train Departed:
/*George Regas

  COP 3502

  g0616085

  Oct 22, 2008

  Assignment 3:

  Bob's Train Station

*/

#include <stdio.h>
 

struct station* new_station(int initial_Size);//stack

struct train* new_train(int initial_size);	//queue

//void print_stack(struct station* s);

void print_queue(struct train* q);//prints elements in queue

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);//function

int isQueueEmpty(struct train* q);//checks to see if queue is empty

int add_car(struct train* q, int car);//adds a car

int AreThereAtLeastTwoEmptySlotInTheQueue(struct train* q);//checks elements in queue

int dequeue(struct train* q);//removes element from queue

void remove_car(struct train* q);//prints output of removing car
 

struct train

{

    int* store;

    int front;

    int back;

	int count;//number of cars in queue

    int size;

};
 

struct station

{

    struct train * store;

    int top;

    int size;

};
 

struct station* new_station(int initial_Size) //my stack

{

    struct station* s;

    

    s = malloc(sizeof(struct station));

    

    s->store = calloc(initial_Size, sizeof(struct train));

    s->top = 0;

    s->size = initial_Size;

    

    return s;

}
 

void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars

{

    int i;

    int j;

    int car;

 

	//printf("Train Departed: ");

	q->count = 0;
 

    for(i = 0; i < num_cars; i++)

    {

        fscanf(fname, "%d", &car);

		printf("%d ", car);

        add_car(q,car);

        //expand queue check

    }

//printf("\n");

 

    s->store[s->top] = (*q);

    s->top++;

    for(j = 0; j < s->top; j++)

    {

//		printf("%d\n", s->store[j]);

    }

    return;   

}
 

int AreThereAtLeastTwoEmptySlotInTheQueue(struct train* q)

{

	return (q->size - q->count) >= 2;

}

struct train* new_train(int initial_size) //my queue

{

    struct train* q;

    

    q = malloc(sizeof(struct train));

    q->store = calloc(initial_size, sizeof(int));

    q->front = 0;

    q->back = 0;

    q->size = initial_size;

    

    return q;   

}
 

void print_queue(struct train* q)

{

	int i;

	

	for(i=q->front; i < q->back; i++)

		printf("%d", q->store[i]);
 

}

void print_stack(struct station* s)

{

      int i; // index used in for loop

    

    // loop through stack from top to bottom, printing them out as we go

    for(i = 0; i < s->top; i++)

        print_queue(s->store);

;

       

}

int isQueueEmpty(struct train* q)// checks to see if the queue is empty

{

	return q->count<2;//because the queue has to have 3 space in it at a minimium

}

int dequeue(struct train* q)

{

    int rval = q->store[q->front];  // value of the integer at the front of the queue
 

    

  

    q->front = (q->front + 1) % q->size;// Move front up one position in the store array

    q->count--;

    

    return rval;// return the value that just got dequeued
 

		q->front = (q->front + 1) % q->size;

		  // this is the new line

}

void remove_car(struct train* q)//removes car from the train   

{

      if(isQueueEmpty(q))//checks to see if there are enough cars to allow the car to be removed

      {

            printf("There is only one car on the train.\n");

            

      }

      else

      {

            int rval=dequeue(q);//returns the value of the car removed

            printf("Car %d has been removed!\n", rval);

      }

}
 
 

void expandqueue(struct train* q)

{

    int i; // used in the for loop below to copy data from old store array to new one

    int* oldstore = q->store; // pointer to the store array

    

    // now, store will point to an array that is twice the size of the old one

    q->store = calloc(q->size * 2, sizeof(int));

    

    // copy the values in the queue from the old store array to the new one

    for(i = 0; i < q->size; i++)

    {

        q->store[i] = oldstore[(i+q->front) % q->size];

    }

   // q->front = 0; // the values from the old array are copied into the beginning of the new array

    //q->back = q->size; // there are q->size elements in the array so that's where back will point

    //q->size = q->size * 2; // the size of the store array has doubled

    free(oldstore); // always free memory that isn't being used

}
 

int add_car(struct train* q, int car)//adds a car to the queue and makes the queue larger is it needs to be

{

    //int data;

		

	if(!AreThereAtLeastTwoEmptySlotInTheQueue(q))

    {

        expandqueue(q);

    }    

	// put the new data into the back of the queue

    q->store[q->back] = car;

	

		//int data = add_car(q);

		//return q;
 

    // Move back up one position in the store array

    // The % (modulus) operator is used to ensure that back does not exceed the size

    //   of the array.

    // Keep in mind that we could loop around in the store array if front > back.

    q->back = (q->back + 1) % q->size;

	q->count++;

		

    

    return q;

}
 

int main(void)//main function

{

	FILE *fp;

    char fname[32];	

	int i, n;

	char action[20];

	struct station* s;

	struct train* q;

	int num_cars, rval, data, car;

	
 

	printf("Welcome to Bob's Train Station\n");

	printf("What is the name of the input file?\n");

	scanf("%s", fname);
 

	fp = fopen(fname, "r");

	if (fp == NULL)

		printf("ERROR");

	

	printf("Here is the output!:\n");

	

	fscanf(fp, "%d", &n);

	s=new_station(10);

	for(i=0; i<n; i++)

	{

		fscanf(fp,"%s", action);

		if(strcmp(action,"new_train")==0)

		{

			//printf("******");

			fscanf(fp, "%d", &num_cars);

			q=new_train(num_cars);				

			add_train(s, q, num_cars, fp);

		}

		else if(strcmp(action, "remove_car")==0)

		{

			//printf("---------");

			remove_car(q);

		}

		else if(strcmp(action, "add_car")==0)

		{

			//printf("add_car\n");

			fscanf(fp, "%d", &car);

			add_car(q, car);

		}

		else if(strcmp(action, "train_departs")==0)

		{

			print_stack(s);

				printf("Train Departed:\n");

			//place funtion here

		}

	}

	fclose(fp);

		

	system("PAUSE");

	return 0;

}

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
One problem -- my mistake -- is that in expandqueue, the line
    q->size = q->size * 2; // the size of the store array has doubled
is needed.

(more coming)
0