Link to home
Start Free TrialLog in
Avatar of mikeregas
mikeregas

asked on

stack of queues

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

Avatar of sunnycoder
sunnycoder
Flag of India image

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
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.
Would you please post the input file  you are using?
Avatar of mikeregas
mikeregas

ASKER

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

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

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

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 ;-)
Remove the semicolon at the end of
            else if(strcmp(action, "remove_car")==0);
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.
>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
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.
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.
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?
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?
Sunny, we have the compilation issues resolved and and working through the logic.
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

I do not need the train departed printf's do I at all
That is correct.  Except that you will need one when handling the train_departs command.
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.
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.
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...")
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

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

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.
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.
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

Thank you for that.  It clarifies several questions that I had.
>>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
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.
>>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
You already have
   int dequeue(struct train* q)
which appears to be coded correctly.

Just use that.
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

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.
Take your time, you are explaining this better than the guys in the computer lab did all day!
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?
Here is a solution to that problem
http://www.soe.ucsc.edu/classes/cmps012b/Spring97/Lecture07/tsld011.htm

(I googled for
   full empty queue
yes so the queue needs to be expanded when it gets full?
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

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.
>>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.
add_car will need to check the queue and call expand_queue if the queue is currently full.
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
>>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.
>>So the check should move from the end of add_car to the beginning of add_car.
Yes

so that function (expandqueue(q)) needs to be added to both add_car and remove_car?
I will need to go to bed in a half hour or so.
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

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
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.
>>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.
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);
    }
      
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
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
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
isnt that where this part of the code compairs the two parts of the queue q->front == q->back
>>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?
>>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.
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
>>Do you still have
   printf("Train Departed: ");
in add_train?

it is coming from: else if(strcmp(action, "train_departs")==0);
>>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.
>>it is coming from: else if(strcmp(action, "train_departs")==0);
Remove the semicolon from the end of the line
damn I feel stupid for not seeing that
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.  
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.)
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

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
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?
yes thank you and I will be here tomorrow. Thanks again and have a good night
>>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.
Good night.
Why don't you post your current code sometime shortly before 6PM Pacific, so that we start off in sync.

Good night.

Joe
sounds good, I will post something around 5 when I get off work and we will go from there.
Thanks again...

Mike
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

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!
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
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.
>>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.
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
>>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
Yes.  Now an empty train is recognized correctly.
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

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);
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?
no it doesnt, I am jsut repeating myself here. right?
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?
actually I need to read the queue first then determine if I need to expand  the queue
>>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.
yes, lets get remove_car and then work on next thing
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)
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?
so instead of you the % I should be adding 1 to the queue everytime a car is added?
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

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?
>>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.

i understand that, makes good sense
>>
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

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?
Actually, given that you're doing Method three, that should be
   AreThereAtLeastTwoEmptySlotsInTheQueue(q)
yes I can give it a try and you tell me where I am worng
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);
      }
}
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);
      }
}
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
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.
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);
      }
}
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
      }
}
Sorry I had a call.  Give me just a moment
no problem
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?
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;
Now IsQueueEmpty becomes very simple
int isQueueEmpty(struct train* q)
{
    return q->count == 0;  
}
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?
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

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
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);
>>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?
>>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);
            }
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"
>>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.
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

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.
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);
    }

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 . . .
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
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 . . .
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;
}
I had the isQueueEmpty at the end
allthough looking at the example the 14 car should not be removed
so it is looping through the last queue right
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;

>>so it is looping through the last queue right
Yes.  This is progress.
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

that means that I need to combine the print queue and printstack
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.

>>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.
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:
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?
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

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)
In main, remove the "Train Departed" printf.  We'll have print_queue print that
            else if(strcmp(action, "train_departs")==0)
            {
                  print_stack(s);
                        //printf("Train Departed:\n");
                  //place funtion here
            }

And then in print_queue, print out a couple of extra things, as in
void print_queue(struct train* q)
{
   int i;
   
   printf("Train departed: ");
   for(i=q->front; i < q->back; i++)
      printf("%d", q->store[i]);
   printf("\n");
}

This gives an output that isn't quite right, yet, but is closer.
Welcome to Bob's Train Station
What is the name of the input file?
Here is the output!:
3 2 4 1 6 4 14 Car 4 has been removed!
There is only one car on the train.
6 7 8 Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Train departed: 32416
Press any key to continue . . .

Let me know if you get this output
that is what I got
Good.  Save a copy of what you have right now.  This is a valuable lesson -- when you have something that is doing a lot of what you need, save a copy of it.  It is disaster insurance.

(more coming)
Actually, I need to debug for a couple of minutes.
lol, I learned that from last night. I think I forgot to save it. So I have been saving away tonight. I am falling in love with Ctrl S.
Good...it is a good lesson to learn.  What I really meant was to make a copy, saving it in another file, preferably on another drive or a memory stick or in the cloud.  

OK, so on to the nxt issue...Why all the
   Train departed: 32416
lines?

First of all, we're printing the wrong thing in main.  Instead of
            else if(strcmp(action, "train_departs")==0)
            {
                  print_stack(s);
            }
we should be printing the last train to arrive, which is at the top of the stack, and not printing the entire station.  So
            else if(strcmp(action, "train_departs")==0)
            {
                  print_queue(&s->store[s->top]);
            }

That cuts down on the excessive printing, but exposes another problem, which we'll fix in a minute.

My output is
Welcome to Bob's Train Station
What is the name of the input file?
Here is the output!:
3 2 4 1 6 4 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:
Press any key to continue . . .

Do you get that result?
That is what I have
where do the numbers come from
I guess I should clarify numbers:32416
They are printed out by add_train.  Remove the line
            printf("%d ", car);
from add_train and they will go away.

I'll discuss the next change in just a moment.
When handling train departure, we have to do two things
1)  If the stack is empty, say that no train departed.
2)  Otherwise
          Print the train that is at the top of the stack.  
          Decrement the stack pointer.

The stack pointer points to the next empty location on the stack.  So the top of the stack is s->top-1

Are you up to writing that?
ok, you are helping me out a lot, I am actually learning here, beats the hell out of my class
That change will print out
     Train departed
but it won't print out the cars.

That's because print_queue needs to first print the car at q->front, then increment q->front, then print the next car, and so on.  Something like this
void print_queue(struct train* q)
{
   int i;
   
   printf("Train departed: ");
   for (i = q->count; i > 0; i--)
   {
      printf("%d ", q->store[q->front]);
      q->front = (q->front + 1) % q->size;// Move front up one position in the store array
   }
   printf("\n");
}
>>I am actually learning here, beats the hell out of my class
That makes my heart glad!
why is it i--? wouldn't that go the wrong direction
You can count down to zero as in
   for (i = q->count; i > 0; i--)
or count up to q->count, as in
   for (i = 0; i < q->count; i++)
It doesn't make any difference, you get the same number of iterations either way.

It merely a matter of style.
how come there are no train numbers
Welcome to Bob's Train Station
What is the name of the input file?
Here is the output!:
Car 4 has been removed!
There is only one car on the train.
Train departed:
Train departed:
Train departed:
Train departed:
Press any key to continue . .
>>It merely a matter of style.

I understand what you are saying
>>how come there are no train numbers

I'm not sure.  Would you post your current code, please?
to print out the Station empty, is that a while statement
something like this:
while (q->count)!=0
here it my code
/*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;
   
   printf("Train departed: ");
   for (i = q->count; i > 0; i--)
   {
      printf("%d ", q->store[q->front]);
      q->front = (q->front + 1) % q->size;// Move front up one position in the store array
   }
   printf("\n");
}
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
    
    
    q->store = calloc(q->size * 2, sizeof(int));// now, store will point to an array that is twice the size of the old one
    
    
    for(i = 0; i < q->size; i++)// copy the values in the queue from the old store array to the new one
    {
        q->store[i] = oldstore[(i+q->front) % q->size];
    }
  
    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)
		{
			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)
		{
			//printf("add_car\n");
			fscanf(fp, "%d", &car);
			add_car(q, car);
		}
		else if(strcmp(action, "train_departs")==0)
		{
			print_queue(&s->store[s->top]);
		}
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}

Open in new window

The problem is in the code handling
            else if(strcmp(action, "train_departs")==0)

It needs to be
            else if(strcmp(action, "train_departs")==0)
            {
                  if (s->top == 0)
                  {
                     printf("Station empty, no train departed.\n");
                  }
                  else
                  {
                     print_queue(&s->store[s->top-1]);
                     s->top--;
                  }
            }
This is what I was talking about when I said

When handling train departure, we have to do two things
1)  If the stack is empty, say that no train departed.
2)  Otherwise
          Print the train that is at the top of the stack.  
          Decrement the stack pointer.

The stack pointer points to the next empty location on the stack.  So the top of the stack is s->top-1
I see what you are saying now. You should teach this stuff, you are very patient
Thank you!
i get myself so confused with all the different syntax, I would say that it is a lot like Calculus, where if you dont know the algebra, you can not do the Calc, if you do not know the syntax you can not write the code.
I am changing the sample.txt file to see what happens. I wish that I could give you more than 500 points. The effort and time that you put into helping me is worth much more than that. It is really rewarding when it all comes together
the stacks loops through till it is empty right
>>so confused with all the different syntax
I understand that very well.  It's like knowing the definitions of words -- you can't express yourself well unless you know the meanings of the words well enough to say things clearly.  It's also like grammar -- English sentences are constructed one way, Spanish sentences are constructed another.  There are similarities and there are differences.

>>It is really rewarding when it all comes together
You are very very welcome!  It is also highly rewarding when you can communicate to another and raise his understanding.  It has some similarities to raising a child (although it is less).  It is so wonderful to watch your child grow and become an adult.  It is something you have created.

Creation is the most joyous act there is.
>>the stacks loops through till it is empty right
I'm not sure what you're asking.  The input data drives the program to an empty station by having all trains depart.

Am I tracking with you?
>>t is so wonderful to watch your child grow and become an adult.  It is something you have created.

I am having my first child in December and I am really looking forward to it, kinda scared, but still really looking forward to it. I am very excited.

and in case I have not said it enough:

THANK YOU!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I think I understand what you are saying, as long as there are enough train_departs to match the new_train the trains will come out of the station, so 1 train_departs removes 1new_train
ASKER CERTIFIED SOLUTION
Avatar of josgood
josgood
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks again Joe and I will do that, spend the time that someone needs to learn what I can help them with.

Have a great night and I will see you around here ..

Mike
>>Thanks again Joe and I will do that
Excellent!  Thank you.

Good night.

Joe
Joe, you really went above and beyond to explain the concept that I was attempting to learn. I really truely appreciate it. I can not thank you enough for your time and patience. Once again, you are an excellent teacher, I can only hope that I was half as good of a student.
THANK YOU!!!!!!!!!!!!!!!!!!!!!!!!
EXCELLENT TEACHING SKILLS