?
Solved

stack of queues

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

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

/*George Regas
  COP 3502
  g0616085
  Oct 22, 2008
  Assignment 3:
  Bob's Train Station
*/
#include <stdio.h>
 
struct station* new_station(int initial_Size);
struct train* new_train(int initial_size);	
void print_stack(struct station* s);
void print_queue(struct train* q);
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);
int remove(struct station* s, struct train* q);
int last_car(struct queue* q);
 
struct train
{
    int* store;
    int front;
    int back;
    int size;
};
 
struct station
{
    struct train * store;
    int top;
    int size;
};
 
struct station* new_station(int initial_Size) //my stack
{
    struct station* s;
    
    s = malloc(sizeof(struct station));
    
    s->store = calloc(initial_Size, sizeof(struct train));
    s->top = 0;
    s->size = initial_Size;
    
    return s;
}
 
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
printf("Train Departed: ");
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		printf("%d ", car);
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
        //expand queue check
    }
printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}
 
struct train* new_train(int initial_size) //my queue
{
    struct train* q;
    
    q = malloc(sizeof(struct train));
    q->store = calloc(initial_size, sizeof(int));
    q->front = 0;
    q->back = 0;
    q->size = initial_size;
    
    return q;   
}
 
void print_queue(struct train* q)
{
	int i;
	
	for(i=q->front; i < q->back; i++)
		printf("%d", q->store[i]);
 
}
void print_stack(struct station* s)
{
    int i; // index used in for loop
    
    // loop through stack from top to bottom, printing them out as we go
    for(i = 0; i < s->top; i++)
        print_queue;
       
}
// This function returns true if the queue is empty and false otherwise
int isQueueEmpty(struct train* q)
{
    // if the front and back are equal to each other then the queue is empty
    return q->front == q->back;   
}
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    // Move front up one position in the store array
    // The % (modulus) operator is used to ensure that front does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->front = (q->front + 1) % q->size;
    
    // return the value that just got dequeued
    return rval;
}
int remove_car(struct train* q)
{
	if (
		isQueueEmpty(s)
		printf("there is only one car on the train.");
}
int main(void)
{
	FILE *fp;
    char fname[32];	
	int i, n;
	char action[20];
	struct station* s;
	struct train* q;
	int num_cars;
 
	printf("Welcome to Bob's Train Station\n");
	printf("What is the name of the input file?\n");
	scanf("%s", fname);
 
	fp = fopen(fname, "r");
	if (fp == NULL)
		printf("ERROR");
	
	printf("Here is the output!:\n");
	
	fscanf(fp, "%d", &n);
	s=new_station(10);
	for(i=0; i<n; i++)
	{
		fscanf(fp,"%s", action);
		if(strcmp(action,"new_train")==0)
		{
			fscanf(fp, "%d", &num_cars);
			q=new_train(num_cars);				
			add_train(s, q, num_cars, fp);
		}
/*		else if(strcmp(action, "remove_car")==0);
		{
			place funtion here
		}
		else if(strcmp(action, "add_car")==0);
		{
			place funtion here
		}
		else if(strcmp(action, "train_departs")==0);
		{
			place funtion here
		}//*/
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}

Open in new window

0
Comment
Question by:mikeregas
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 86
  • 84
  • 4
174 Comments
 
LVL 45

Expert Comment

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

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

    add an element to the end of the queue

    return success
}

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

    remove element from head of the queue

    return success
}

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

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

Expert Comment

by:josgood
ID: 22782485
I see some initial problems

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

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

I'll look further.
0
 
LVL 13

Expert Comment

by:josgood
ID: 22782499
Would you please post the input file  you are using?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:mikeregas
ID: 22782537
what am I doing worng in the function int remove_car()?
/*George Regas
  COP 3502
  g0616085
  Oct 22, 2008
  Assignment 3:
  Bob's Train Station
*/
#include <stdio.h>
 
struct station* new_station(int initial_Size);
struct train* new_train(int initial_size);	
void print_stack(struct station* s);
void print_queue(struct train* q);
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);
int last_car(struct queue* q);
int isQueueEmpty(struct train* q);
 
struct train
{
    int* store;
    int front;
    int back;
    int size;
};
 
struct station
{
    struct train * store;
    int top;
    int size;
};
 
struct station* new_station(int initial_Size) //my stack
{
    struct station* s;
    
    s = malloc(sizeof(struct station));
    
    s->store = calloc(initial_Size, sizeof(struct train));
    s->top = 0;
    s->size = initial_Size;
    
    return s;
}
 
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
printf("Train Departed: ");
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		printf("%d ", car);
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
        //expand queue check
    }
printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}
 
struct train* new_train(int initial_size) //my queue
{
    struct train* q;
    
    q = malloc(sizeof(struct train));
    q->store = calloc(initial_size, sizeof(int));
    q->front = 0;
    q->back = 0;
    q->size = initial_size;
    
    return q;   
}
 
void print_queue(struct train* q)
{
	int i;
	
	for(i=q->front; i < q->back; i++)
		printf("%d", q->store[i]);
 
}
void print_stack(struct station* s)
{
    int i; // index used in for loop
    
    // loop through stack from top to bottom, printing them out as we go
    for(i = 0; i < s->top; i++)
        print_queue;
       
}
// This function returns true if the queue is empty and false otherwise
int isQueueEmpty(struct train* q)
{
    // if the front and back are equal to each other then the queue is empty
    return q->front == q->back;   
}
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    // Move front up one position in the store array
    // The % (modulus) operator is used to ensure that front does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->front = (q->front + 1) % q->size;
    
    // return the value that just got dequeued
    return rval;
}
int remove_car(struct train* q)
{
	if(isQueueEmpty(q)==1)
	{
		printf("There is only one car on the train.\n");
		return q;
	}
 
	else if(remove_car)
	{
		dequeue(q);
		printf("Car %d has been removed!\n", &q);
	}
}
int main(void)
{
	FILE *fp;
    char fname[32];	
	int i, n;
	char action[20];
	struct station* s;
	struct train* q;
	int num_cars;
 
	printf("Welcome to Bob's Train Station\n");
	printf("What is the name of the input file?\n");
	scanf("%s", fname);
 
	fp = fopen(fname, "r");
	if (fp == NULL)
		printf("ERROR");
	
	printf("Here is the output!:\n");
	
	fscanf(fp, "%d", &n);
	s=new_station(10);
	for(i=0; i<n; i++)
	{
		fscanf(fp,"%s", action);
		if(strcmp(action,"new_train")==0)
		{
			fscanf(fp, "%d", &num_cars);
			q=new_train(num_cars);				
			add_train(s, q, num_cars, fp);
		}
		else if(strcmp(action, "remove_car")==0);
		{
			remove_car(q);
		}
	/*	else if(strcmp(action, "add_car")==0);
		{
			place funtion here
		}
		else if(strcmp(action, "train_departs")==0);
		{
			place funtion here
		}//*/
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}
	

Open in new window

0
 

Author Comment

by:mikeregas
ID: 22782543
here is the input file
10
new_train 5 3 2 4 1 6
new_train 2 4 14
remove_car
remove_car
new_train 3 6 7 8 
train_departs
add_car 15
train_departs
train_departs
train_departs

Open in new window

0
 

Author Comment

by:mikeregas
ID: 22782565
there is alot more that I need to work out, but I am trying to do it one piece at a time. Here is what the output should look like
Sample Run
Welcome to Bob's train station
What is the name of the input file?
sample1.txt
Here is the output:
Car 4 removed!
Car not removed because there is only one car on the train!
Train departed: 6 7 8
Train departed: 14 15
Train departed: 3 2 4 1 6
Station empty, no train departed!

Open in new window

0
 
LVL 45

Expert Comment

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

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

Expert Comment

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

Author Comment

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

Expert Comment

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

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

Expert Comment

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

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

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

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

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

Author Comment

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

Expert Comment

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

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

Expert Comment

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

Expert Comment

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

Author Comment

by:mikeregas
ID: 22783015
this is where I am as of now, still confused as hell. I know that I need to call functions in order to make all of this come together, but they are becoming more and more confusing.
/*George Regas
  COP 3502
  g0616085
  Oct 22, 2008
  Assignment 3:
  Bob's Train Station
*/
#include <stdio.h>
 
struct station* new_station(int initial_Size);
struct train* new_train(int initial_size);	
void print_stack(struct station* s);
void print_queue(struct train* q);
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);
int last_car(struct queue* q);
int isQueueEmpty(struct train* q);
 
struct train
{
    int* store;
    int front;
    int back;
    int size;
};
 
struct station
{
    struct train * store;
    int top;
    int size;
};
 
struct station* new_station(int initial_Size) //my stack
{
    struct station* s;
    
    s = malloc(sizeof(struct station));
    
    s->store = calloc(initial_Size, sizeof(struct train));
    s->top = 0;
    s->size = initial_Size;
    
    return s;
}
 
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
printf("Train Departed: ");
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		printf("%d ", car);
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
        //expand queue check
    }
printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}
 
struct train* new_train(int initial_size) //my queue
{
    struct train* q;
    
    q = malloc(sizeof(struct train));
    q->store = calloc(initial_size, sizeof(int));
    q->front = 0;
    q->back = 0;
    q->size = initial_size;
    
    return q;   
}
 
void print_queue(struct train* q)
{
	int i;
	
	for(i=q->front; i < q->back; i++)
		printf("%d", q->store[i]);
 
}
void print_stack(struct station* s)
{
    int i; // index used in for loop
    
    // loop through stack from top to bottom, printing them out as we go
    for(i = 0; i < s->top; i++)
        print_queue;
       
}
// This function returns true if the queue is empty and false otherwise
int isQueueEmpty(struct train* q)
{
    // if the front and back are equal to each other then the queue is empty
    return q->front == q->back;   
}
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    // Move front up one position in the store array
    // The % (modulus) operator is used to ensure that front does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->front = (q->front + 1) % q->size;
    
    // return the value that just got dequeued
    return rval;
}
void remove_car(struct train* q, int rval)
{
	
	if(isQueueEmpty(q)==1)
	{
		printf("There is only one car on the train.\n");
		printf("---------");
		return q;
		printf("------");
	}
	
	else if(remove_car)
	{
		
		dequeue(q);
		printf("Car %d has been removed!\n", &rval);
	}
}
void expandqueue(struct train* q)
{
    int i; // used in the for loop below to copy data from old store array to new one
    int* oldstore = q->store; // pointer to the store array
    
    // now, store will point to an array that is twice the size of the old one
    q->store = calloc(q->size * 2, sizeof(int));
    
    // copy the values in the queue from the old store array to the new one
    for(i = 0; i < q->size; i++)
    {
        q->store[i] = oldstore[(i+q->front) % q->size];
    }
    q->front = 0; // the values from the old array are copied into the beginning of the new array
    q->back = q->size; // there are q->size elements in the array so that's where back will point
    q->size = q->size * 2; // the size of the store array has doubled
    free(oldstore); // always free memory that isn't being used
}
 
int add_car(struct train* q, int data)
{
    // put the new data into the back of the queue
    q->store[q->back] = data;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
 
    // double the size of the array if we have run out of space in the current store array
    if(q->front == q->back)
    {
        expandqueue(q);
    }   
}
 
int main(void)
{
	FILE *fp;
    char fname[32];	
	int i, n;
	char action[20];
	struct station* s;
	struct train* q;
	int num_cars, rval;
 
	printf("Welcome to Bob's Train Station\n");
	printf("What is the name of the input file?\n");
	scanf("%s", fname);
 
	fp = fopen(fname, "r");
	if (fp == NULL)
		printf("ERROR");
	
	printf("Here is the output!:\n");
	
	fscanf(fp, "%d", &n);
	s=new_station(10);
	for(i=0; i<n; i++)
	{
		fscanf(fp,"%s", action);
		if(strcmp(action,"new_train")==0)
		{
			fscanf(fp, "%d", &num_cars);
			q=new_train(num_cars);				
			add_train(s, q, num_cars, fp);
		}
		else if(strcmp(action, "remove_car")==0)
		{
			remove_car(q, rval);
		}
	/*	else if(strcmp(action, "add_car")==0)
		{
			add_car(q);
		}
		else if(strcmp(action, "train_departs")==0);
		{
			place funtion here
		}//*/
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}

Open in new window

0
 

Author Comment

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

Expert Comment

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

Expert Comment

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

Expert Comment

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

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

Author Comment

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

Author Comment

by:mikeregas
ID: 22783043
here is all the functions for the remove_car function
int isQueueEmpty(struct train* q)
{
    // if the front and back are equal to each other then the queue is empty
    return q->front == q->back;   
}
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    // Move front up one position in the store array
    // The % (modulus) operator is used to ensure that front does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->front = (q->front + 1) % q->size;
    
    // return the value that just got dequeued
    return rval;
}
void remove_car(struct train* q, int rval)
{
	
	if(isQueueEmpty(q)==1)
	{
		printf("There is only one car on the train.\n");
		printf("---------");
		return q;
		
	}
	
	else if(remove_car)
	{
		
		dequeue(q);
		printf("Car %d has been removed!\n", &rval);
	}
}

Open in new window

0
 

Author Comment

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

int main(void)
{
	FILE *fp;
    char fname[32];	
	int i, n;
	char action[20];
	struct station* s;
	struct train* q;
	int num_cars, rval;
 
	printf("Welcome to Bob's Train Station\n");
	printf("What is the name of the input file?\n");
	scanf("%s", fname);
 
	fp = fopen(fname, "r");
	if (fp == NULL)
		printf("ERROR");
	
	printf("Here is the output!:\n");
	
	fscanf(fp, "%d", &n);
	s=new_station(10);
	for(i=0; i<n; i++)
	{
		fscanf(fp,"%s", action);
		if(strcmp(action,"new_train")==0)
		{
			fscanf(fp, "%d", &num_cars);
			q=new_train(num_cars);				
			add_train(s, q, num_cars, fp);
		}
		else if(strcmp(action, "remove_car")==0)
		{
			remove_car(q, rval);
		}
	/*	else if(strcmp(action, "add_car")==0)
		{
			add_car(q);
		}
		else if(strcmp(action, "train_departs")==0);
		{
			place funtion here
		}//*/
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}

Open in new window

0
 
LVL 13

Expert Comment

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

Let me take the last thing you said first.

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

Expert Comment

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

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

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

Author Comment

by:mikeregas
ID: 22783088
here is the assignment I will just post it and you can see if it will make it easier for you to understand what I am asking or how to explain to me where I am messing up
Objective
1.  Learn how to manipulate stacks and queues in a basic fashion
 
Problem: Train Station 
Bob owns a train station at the end of a rail line.  Trains arrive and depart the station.  Also, while at the station, a train can have cars added to or removed from it.  Because Bob's station is at the end of the rail, only the last train that has arrived can leave his station, i.e., Bob's station works like a stack.  Only the last train that has entered the station can have cars added to or removed from it.  Cars are removed from the front of the train and are added to the back of the train, i.e., the trains act like queues.  Sometimes Bob's employees make mistakes and try to remove cars from trains that only have one car.  Bob does not want this to occur and wants you to write a program to ensure that this doesn't happen.
 
Your program must read in an input file describing the train schedule for the day. The input file will be a text file in the format described here. The input file will begin with a single positive integer, n, on a line by itself indicating the number of events in the schedule. On each of the next n lines is a description of an event. An event will take one of the following forms:
 
A train arrives
Train arrival events take the following form:
new_train n x1 x2 ... xn
where n is a positive integer indicating the number of cars in the new train. The numbers x1 through xn are the current cars in the train.  Car x1 is the first car and xn is the last car.  Thus, x1 will be the first car removed from this train if one were to be removed.
 
A train departs
Train departure events take the following form:
train_departs
This indicates that the last train that has entered the station will depart, and you should print out the cars that are in the train:
Train departed: x1 x2 ... xn
where n is the number of cars in the train that departed, and x1, x2, ..., xn, are the numbers of the cars in that train.  If there is no train in the station, your program should print out
Station empty, no train departed!
 
A car is detached from a train
Car detachment events take the following form:
remove_car
When this happens, you should delete the first car from the train that last entered into the station and print:
Car x removed!
where x is the number of the car that was removed.  If the train has only one car, then your program should not remove the car and instead print:
Car not removed because there is only one car on the train!
If there is no train in the station, your program should print:
Car not removed because there are no trains!
 
A car is attached to a train
Car attachment events take the following form:
add_car n
where n is an integer indicating the car number.  This new car should be added to the back of the train that last entered the station.  If there is no train in the station, your program should instead print:
Car not added because there are no trains!
Output Sample
Here is a sample output of running the program. Note that this test is NOT a comprehensive test. You should test your program with different data than is shown here based on the specifications given. You are free and even encouraged to have your output look different from the sample so long as your program obeys the problem statement. The user input is given in italics while the program output is in bold.
 
Sample input file (sample1.txt)
10
new_train 5 3 2 4 1 6
new_train 2 4 14
remove_car
remove_car
new_train 3 6 7 8
train_departs
add_car 15
train_departs
train_departs
train_departs
 
Sample Run
Welcome to Bob's train station
What is the name of the input file?
sample1.txt
Here is the output:
Car 4 removed!
Car not removed because there is only one car on the train!
Train departed: 6 7 8
Train departed: 14 15
Train departed: 3 2 4 1 6
Station empty, no train departed!
 
Output Explanation
Train #1 with cars <3,2,4,1,6> enters the station.  Then Train #2 with cars <4,14> enters in front of Train #1. Train #2 then has its #4 car removed, but doesn't have #14 removed because that is the only car left. Then, Train #3 enters in front of Train #2, and quickly leaves.  Next, car #15 is added to the back of Train #2, which then departs the station.  Next, Train #1 departs.  Finally, we try to depart a train from the station, but there aren't any left!
 
Deliverables
You must submit the source code for your programs over WebCourses by 11:55 PM on Wednesday, October 22nd, 2008.
 
Restrictions
Although you may use other compilers, your program must compile and run using Dev C++. Please use Dev C++ or another similar environment to develop your programs. Your program should include a header comment with the following information: your name, course number, assignment title, and date. Also, make sure you include comments throughout your code describing the major steps in solving the problem.

Open in new window

0
 
LVL 13

Expert Comment

by:josgood
ID: 22783111
Thank you for that.  It clarifies several questions that I had.
0
 

Author Comment

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

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

Expert Comment

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

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

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

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

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

Author Comment

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

Expert Comment

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

Just use that.
0
 

Author Comment

by:mikeregas
ID: 22783152
dequeue(q);//I called the function
            printf("Car %d has been removed!\n", rval);//this pulls its value?
void remove_car(struct train* q)
{
	int rval;
	//fscanf(fp, "%d");
 
	if(isQueueEmpty(q)==1)
	{
		printf("There is only one car on the train.\n");
		printf("---------");
		return q;
		
	}
	
	else if(remove_car)
	{
		
		dequeue(q);
		printf("Car %d has been removed!\n", rval);
	}
}

Open in new window

0
 
LVL 13

Expert Comment

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

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

Author Comment

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

Expert Comment

by:josgood
ID: 22783185
Thank you!

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

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

Is that making sense to you?
0
 
LVL 13

Expert Comment

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

(I googled for
   full empty queue
0
 

Author Comment

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

Author Comment

by:mikeregas
ID: 22783202
doesnt this make the queue bigger when it needs to be bigger?
void expandqueue(struct train* q)
{
    int i; // used in the for loop below to copy data from old store array to new one
    int* oldstore = q->store; // pointer to the store array
    
    // now, store will point to an array that is twice the size of the old one
    q->store = calloc(q->size * 2, sizeof(int));
    
    // copy the values in the queue from the old store array to the new one
    for(i = 0; i < q->size; i++)
    {
        q->store[i] = oldstore[(i+q->front) % q->size];
    }
    q->front = 0; // the values from the old array are copied into the beginning of the new array
    q->back = q->size; // there are q->size elements in the array so that's where back will point
    q->size = q->size * 2; // the size of the store array has doubled
    free(oldstore); // always free memory that isn't being used
}

Open in new window

0
 
LVL 13

Expert Comment

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

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

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

Expert Comment

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

Expert Comment

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

Author Comment

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

Expert Comment

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

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

Expert Comment

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

0
 

Author Comment

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

Expert Comment

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

Author Comment

by:mikeregas
ID: 22783238
this is what you are saying that it needs to check before the function actually runs to see if it needs to make more room.
void remove_car(struct train* q)
{
	int rval;
	//fscanf(fp, "%d");
 
	 if(q->front == q->back)
    {
        expandqueue(q);
    }
	if(isQueueEmpty(q)==0)
	{
		printf("There is only one car on the train.\n");
		//printf("---------");
		return q;
		
	}
	
	else if(remove_car)
	{
		
		int rval=dequeue(q);
		printf("Car %d has been removed!\n", rval);
	}
}
 
int add_car(struct train* q, int data)
{
     if(q->front == q->back)
    {
        expandqueue(q);// double the size of the array if we have run out of space in the current store array
    }
	// put the new data into the back of the queue
    q->store[q->back] = data;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
 
    
      
}

Open in new window

0
 

Author Comment

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

Expert Comment

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

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

Expert Comment

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

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

Author Comment

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

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

Author Comment

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

Expert Comment

by:josgood
ID: 22783269
Yes, you are.

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

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

(I googled for
   full empty queue
0
 

Author Comment

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

Author Comment

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

Expert Comment

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

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

Expert Comment

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

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

Author Comment

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

Author Comment

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

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

Author Comment

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

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

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

Expert Comment

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

Author Comment

by:mikeregas
ID: 22783318
damn I feel stupid for not seeing that
0
 
LVL 13

Expert Comment

by:josgood
ID: 22783323
Method 3 works for me.

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

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

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

Expert Comment

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

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

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

Author Comment

by:mikeregas
ID: 22783338
I put the expandqueue in the add_car function and I commented on where I thought the add_car should go int he add_train function
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
	//printf("Train Departed: ");
    //here is where I would placce the add_car function
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		//printf("%d ", car);
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
        //expand queue check
    }
//printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}
 
int add_car(struct train* q, int data)
{
     if(q->front == q->back)
    {
        expandqueue(q);// double the size of the array if we have run out of space in the current store array
    }
	// put the new data into the back of the queue
    q->store[q->back] = data;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
 
    
      
}

Open in new window

0
 

Author Comment

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

Expert Comment

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

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

Author Comment

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

Expert Comment

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

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

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

Expert Comment

by:josgood
ID: 22783359
Good night.
0
 
LVL 13

Expert Comment

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

Good night.

Joe
0
 

Author Comment

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

Mike
0
 

Author Comment

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

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


/*George Regas
  COP 3502
  g0616085
  Oct 22, 2008
  Assignment 3:
  Bob's Train Station
*/
#include <stdio.h>
 
struct station* new_station(int initial_Size);
struct train* new_train(int initial_size);	
void print_stack(struct station* s);
void print_queue(struct train* q);
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);
int last_car(struct queue* q);
int isQueueEmpty(struct train* q);
 
struct train
{
    int* store;
    int front;
    int back;
    int size;
};
 
struct station
{
    struct train * store;
    int top;
    int size;
};
 
struct station* new_station(int initial_Size) //my stack
{
    struct station* s;
    
    s = malloc(sizeof(struct station));
    
    s->store = calloc(initial_Size, sizeof(struct train));
    s->top = 0;
    s->size = initial_Size;
    
    return s;
}
 
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
	//printf("Train Departed: ");
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		//printf("%d ", car);
        q->store[q->back] = car;
        q->back = (q->back + 1) % q->size;
        //expand queue check
    }
//printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}
 
struct train* new_train(int initial_size) //my queue
{
    struct train* q;
    
    q = malloc(sizeof(struct train));
    q->store = calloc(initial_size, sizeof(int));
    q->front = 0;
    q->back = 0;
    q->size = initial_size;
    
    return q;   
}
 
void print_queue(struct train* q)
{
	int i;
	
	for(i=q->front; i < q->back; i++)
		printf("%d", q->store[i]);
 
}
void print_stack(struct station* s)
{
    int i; // index used in for loop
    
    // loop through stack from top to bottom, printing them out as we go
    for(i = 0; i < s->top; i++)
        print_queue;
       
}
// This function returns true if the queue is empty and false otherwise
int isQueueEmpty(struct train* q)
{
    // if the front and back are equal to each other then the queue is empty
    return q->front == q->back;   
}
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    // Move front up one position in the store array
    // The % (modulus) operator is used to ensure that front does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->front = (q->front + 1) % q->size;
    
    // return the value that just got dequeued
    return rval;
}
void remove_car(struct train* q)
{
	int rval;
	//fscanf(fp, "%d");
 
	 
	if(isQueueEmpty(q)==0)
	{
		printf("There is only one car on the train.\n");
		return q;
		
	}
	
	else if(remove_car)
	{
		
		int rval=dequeue(q);
		printf("Car %d has been removed!\n", q);
	}
}
 
void expandqueue(struct train* q)
{
    int i; // used in the for loop below to copy data from old store array to new one
    int* oldstore = q->store; // pointer to the store array
    
    // now, store will point to an array that is twice the size of the old one
    q->store = calloc(q->size * 2, sizeof(int));
    
    // copy the values in the queue from the old store array to the new one
    for(i = 0; i < q->size; i++)
    {
        q->store[i] = oldstore[(i+q->front) % q->size];
    }
    q->front = 0; // the values from the old array are copied into the beginning of the new array
    q->back = q->size; // there are q->size elements in the array so that's where back will point
    q->size = q->size * 2; // the size of the store array has doubled
    free(oldstore); // always free memory that isn't being used
}
 
int add_car(struct train* q)
{
    int data;
		
	if(q->front == q->back)
    {
        expandqueue(q);
    }  
	// put the new data into the back of the queue
    q->store[q->back] = data;
		int data = add_car(q);
		return q;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
		
    // double the size of the array if we have run out of space in the current store array
     
}
 
int main(void)
{
	FILE *fp;
    char fname[32];	
	int i, n;
	char action[20];
	struct station* s;
	struct train* q;
	int num_cars, rval, data;
 
	printf("Welcome to Bob's Train Station\n");
	printf("What is the name of the input file?\n");
	scanf("%s", fname);
 
	fp = fopen(fname, "r");
	if (fp == NULL)
		printf("ERROR");
	
	printf("Here is the output!:\n");
	
	fscanf(fp, "%d", &n);
	s=new_station(10);
	for(i=0; i<n; i++)
	{
		fscanf(fp,"%s", action);
		if(strcmp(action,"new_train")==0)
		{
			//printf("******");
			fscanf(fp, "%d", &num_cars);
			q=new_train(num_cars);				
			add_train(s, q, num_cars, fp);
		}
		else if(strcmp(action, "remove_car")==0)
		{
			//printf("---------");
			remove_car(q);
		}
		else if(strcmp(action, "add_car")==0)
		{
			printf("add_car\n");
			add_car(q);
		}
		else if(strcmp(action, "train_departs")==0)
		{
			printf("Train Departed:\n");
			//place funtion here
		}
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}

Open in new window

0
 
LVL 13

Expert Comment

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

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

And you're very welcome!
0
 

Author Comment

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

Expert Comment

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

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

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

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

Expert Comment

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

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

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

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

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

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

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

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

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

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

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

Author Comment

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

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

Author Comment

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

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

Expert Comment

by:josgood
ID: 22792597
Yes.  Now an empty train is recognized correctly.
0
 

Author Comment

by:mikeregas
ID: 22792604
in the add_car function I think that I have addressed it below properly. take a look and let me know if I am going in the right direction
int add_car(struct train* q)
{
    int data;
		
	if(q->front == q->back)
    {
        expandqueue(q);
    }  
	// put the new data into the back of the queue
    q->store[q->back] = q;
		//int data = add_car(q);
		return q;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
		
    // double the size of the array if we have run out of space in the current store array
     
}

Open in new window

0
 

Author Comment

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

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

Expert Comment

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

That doesn't make sense, does it?
0
 

Author Comment

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

Expert Comment

by:josgood
ID: 22792636
Let's do one thing at a time.

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

Are we in sync?
0
 

Author Comment

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

Expert Comment

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

Let's get in sync.  I'll wait for you to respond to my last question.
0
 

Author Comment

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

Expert Comment

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

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

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

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

(more coming)
0
 
LVL 13

Expert Comment

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

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

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

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

Make sense so far?
0
 

Author Comment

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

Author Comment

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

I know what you are saying, so it should look like this
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
	//printf("Train Departed: ");
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		//printf("%d ", car);
         add_card(q,car);
         add_card(q,car);
        //expand queue check
    }
//printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}

Open in new window

0
 
LVL 13

Expert Comment

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

So far, so good?
0
 
LVL 13

Expert Comment

by:josgood
ID: 22792745
>>add_card(q,car);
>>add_card(q,car);

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

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

0
 

Author Comment

by:mikeregas
ID: 22792748
i understand that, makes good sense
0
 

Author Comment

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

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

I thought that it looked a littel out of place calling the same function twice.
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
	//printf("Train Departed: ");
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		//printf("%d ", car);
         add_card(q,car);
        //expand queue check
    }
//printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}

Open in new window

0
 
LVL 13

Expert Comment

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

OK, so then, what to do with add_car?

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

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

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

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

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

Expert Comment

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

Author Comment

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

Expert Comment

by:josgood
ID: 22792782
0
 

Author Comment

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

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

Expert Comment

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

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

Author Comment

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

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

Expert Comment

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

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

Author Comment

by:mikeregas
ID: 22792836
is this a litle better looking ?

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

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

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

Author Comment

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

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

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

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

Expert Comment

by:josgood
ID: 22792881
Sorry I had a call.  Give me just a moment
0
 

Author Comment

by:mikeregas
ID: 22792886
no problem
0
 
LVL 13

Expert Comment

by:josgood
ID: 22792896
Here's code that expresses what I am trying to say

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

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

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

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

Does that make sense?
0
 
LVL 13

Expert Comment

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

Expert Comment

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

Expert Comment

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

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

Author Comment

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

int add_car(struct train* q, int car)
{
    //int data;
		
	if(!AreThereAtLeastTwoEmptySlotsInTheQueue(q))
    {
        expandqueue(q);
    }    
	// put the new data into the back of the queue
    q->store[q->back] = car;
	q->count++;
		//int data = add_car(q);
		return q;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
		
    // double the size of the array if we have run out of space in the current store array
     if(isQueueEmpty(q))
    {
        expandqueue(q);
    }
}
 
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    // Move front up one position in the store array
    // The % (modulus) operator is used to ensure that front does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->front = (q->front + 1) % q->size;
    
    // return the value that just got dequeued
    return rval;
 
		q->front = (q->front + 1) % q->size;
		q->count--;  // this is the new line
}
 
int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q)
{
	return (q->size - q->count) >= 2;
}

Open in new window

0
 

Author Comment

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

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

Author Comment

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

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

add_car(q, car);
0
 
LVL 13

Expert Comment

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

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

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

Does that make sense?
0
 
LVL 13

Expert Comment

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

Author Comment

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

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

Expert Comment

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

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

Author Comment

by:mikeregas
ID: 22793066
I added the prototypes and it gave me the same errors. I have attached my program code so maybe you can see where my error is.
/*George Regas
  COP 3502
  g0616085
  Oct 22, 2008
  Assignment 3:
  Bob's Train Station
*/
#include <stdio.h>
 
struct station* new_station(int initial_Size);
struct train* new_train(int initial_size);	
void print_stack(struct station* s);
void print_queue(struct train* q);
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);
int last_car(struct queue* q);
int isQueueEmpty(struct train* q);
int add_car(struct train* q, int car);
int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q);
 
struct train
{
    int* store;
    int front;
    int back;
	int count;//number of cars in queue
    int size;
};
 
struct station
{
    struct train * store;
    int top;
    int size;
};
 
struct station* new_station(int initial_Size) //my stack
{
    struct station* s;
    
    s = malloc(sizeof(struct station));
    
    s->store = calloc(initial_Size, sizeof(struct train));
    s->top = 0;
    s->size = initial_Size;
    
    return s;
}
 
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
	//printf("Train Departed: ");
	q->count = 0;
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		//printf("%d ", car);
         add_card(q,car);
        //expand queue check
    }
//printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}
 
int IsThereAtLeastTwoEmptySlotInTheQueue(struct train* q)
{
	return (q->size - q->count) >= 2;
}
struct train* new_train(int initial_size) //my queue
{
    struct train* q;
    
    q = malloc(sizeof(struct train));
    q->store = calloc(initial_size, sizeof(int));
    q->front = 0;
    q->back = 0;
    q->size = initial_size;
    
    return q;   
}
 
void print_queue(struct train* q)
{
	int i;
	
	for(i=q->front; i < q->back; i++)
		printf("%d", q->store[i]);
 
}
/*void print_stack(struct station* s)
{
    int i; // index used in for loop
    
    // loop through stack from top to bottom, printing them out as we go
    for(i = 0; i < s->top; i++)
        print_queue;
       
}*/
int isQueueEmpty(struct train* q)// checks to see if the queue is empty
{
	return q->count == 2;//because the queue has to have 3 space in it at a minimium
}
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    
  
    q->front = (q->front + 1) % q->size;// Move front up one position in the store array
    
    
    return rval;// return the value that just got dequeued
 
		q->front = (q->front + 1) % q->size;
		q->count--;  // this is the new line
}
void remove_car(struct train* q)//removes car from the train   
{
      if(isQueueEmpty(q))//checks to see if there are enough cars to allow the car to be removed
      {
            printf("There is only one car on the train.\n");
            
      }
      else
      {
            int rval=dequeue(q);//returns the value of the car removed
            printf("Car %d has been removed!\n", rval);
      }
}
 
 
void expandqueue(struct train* q)
{
    int i; // used in the for loop below to copy data from old store array to new one
    int* oldstore = q->store; // pointer to the store array
    
    // now, store will point to an array that is twice the size of the old one
    q->store = calloc(q->size * 2, sizeof(int));
    
    // copy the values in the queue from the old store array to the new one
    for(i = 0; i < q->size; i++)
    {
        q->store[i] = oldstore[(i+q->front) % q->size];
    }
    q->front = 0; // the values from the old array are copied into the beginning of the new array
    q->back = q->size; // there are q->size elements in the array so that's where back will point
    q->size = q->size * 2; // the size of the store array has doubled
    free(oldstore); // always free memory that isn't being used
}
 
int add_car(struct train* q, int car)
{
    //int data;
		
	if(!AreThereAtLeastTwoEmptySlotsInTheQueue(q))
    {
        expandqueue(q);
    }    
	// put the new data into the back of the queue
    q->store[q->back] = car;
	
		//int data = add_car(q);
		return q;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
		
    // double the size of the array if we have run out of space in the current store array
     if(isQueueEmpty(q))
    {
        expandqueue(q);
    }
}
 
int main(void)
{
	FILE *fp;
    char fname[32];	
	int i, n;
	char action[20];
	struct station* s;
	struct train* q;
	int num_cars, rval, data, car;
	
 
	printf("Welcome to Bob's Train Station\n");
	printf("What is the name of the input file?\n");
	scanf("%s", fname);
 
	fp = fopen(fname, "r");
	if (fp == NULL)
		printf("ERROR");
	
	printf("Here is the output!:\n");
	
	fscanf(fp, "%d", &n);
	s=new_station(10);
	for(i=0; i<n; i++)
	{
		fscanf(fp,"%s", action);
		if(strcmp(action,"new_train")==0)
		{
			//printf("******");
			fscanf(fp, "%d", &num_cars);
			q=new_train(num_cars);				
			add_train(s, q, num_cars, fp);
		}
		else if(strcmp(action, "remove_car")==0)
		{
			//printf("---------");
			remove_car(q);
		}
		else if(strcmp(action, "add_car")==0)
		{
			//printf("add_car\n");
			fscanf(fp, "%d", &car);
			add_car(q, car);
		}
		else if(strcmp(action, "train_departs")==0)
		{
			printf("Train Departed:\n");
			//place funtion here
		}
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}

Open in new window

0
 
LVL 13

Expert Comment

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

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

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

Expert Comment

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

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

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

0
 
LVL 13

Expert Comment

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

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

Author Comment

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

Now I guess poping the stack is next
0
 

Author Comment

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

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

Expert Comment

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

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

Author Comment

by:mikeregas
ID: 22793258
I had the isQueueEmpty at the end
0
 

Author Comment

by:mikeregas
ID: 22793265
allthough looking at the example the 14 car should not be removed
0
 

Author Comment

by:mikeregas
ID: 22793274
so it is looping through the last queue right
0
 
LVL 13

Expert Comment

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

add_car needs a
    q->count++;

dequeue needs a
    q->count--;

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

0
 
LVL 13

Expert Comment

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

Author Comment

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

this is what I have for printing so far

/*void print_stack(struct station* s)
{
    int i; // index used in for loop
    
    // loop through stack from top to bottom, printing them out as we go
    for(i = 0; i < s->top; i++)
        print_queue;
       
}*/

Open in new window

0
 

Author Comment

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

Expert Comment

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

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

That looks like it will work.

0
 
LVL 13

Expert Comment

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

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

Author Comment

by:mikeregas
ID: 22793426
my output looks something like this

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

Expert Comment

by:josgood
ID: 22793464
Yes.  There are two problems.

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

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

I talk about the other problem shortly.

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

Author Comment

by:mikeregas
ID: 22793494
my output does not have the 32416 in it?

Here is the output:!
3 2 4 1 6 14 Car 4 has been removed!
There is only one car on the train.
6 7 8 Train Departed:
Train Departed:
Train Departed:
Train Departed:
/*George Regas
  COP 3502
  g0616085
  Oct 22, 2008
  Assignment 3:
  Bob's Train Station
*/
#include <stdio.h>
 
struct station* new_station(int initial_Size);//stack
struct train* new_train(int initial_size);	//queue
//void print_stack(struct station* s);
void print_queue(struct train* q);//prints elements in queue
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname);//function
int isQueueEmpty(struct train* q);//checks to see if queue is empty
int add_car(struct train* q, int car);//adds a car
int AreThereAtLeastTwoEmptySlotInTheQueue(struct train* q);//checks elements in queue
int dequeue(struct train* q);//removes element from queue
void remove_car(struct train* q);//prints output of removing car
 
struct train
{
    int* store;
    int front;
    int back;
	int count;//number of cars in queue
    int size;
};
 
struct station
{
    struct train * store;
    int top;
    int size;
};
 
struct station* new_station(int initial_Size) //my stack
{
    struct station* s;
    
    s = malloc(sizeof(struct station));
    
    s->store = calloc(initial_Size, sizeof(struct train));
    s->top = 0;
    s->size = initial_Size;
    
    return s;
}
 
void add_train(struct station* s, struct train* q, int num_cars, FILE* fname)//function for reading the train with the cars
{
    int i;
    int j;
    int car;
 
	//printf("Train Departed: ");
	q->count = 0;
 
    for(i = 0; i < num_cars; i++)
    {
        fscanf(fname, "%d", &car);
		printf("%d ", car);
        add_car(q,car);
        //expand queue check
    }
//printf("\n");
 
    s->store[s->top] = (*q);
    s->top++;
    for(j = 0; j < s->top; j++)
    {
//		printf("%d\n", s->store[j]);
    }
    return;   
}
 
int AreThereAtLeastTwoEmptySlotInTheQueue(struct train* q)
{
	return (q->size - q->count) >= 2;
}
struct train* new_train(int initial_size) //my queue
{
    struct train* q;
    
    q = malloc(sizeof(struct train));
    q->store = calloc(initial_size, sizeof(int));
    q->front = 0;
    q->back = 0;
    q->size = initial_size;
    
    return q;   
}
 
void print_queue(struct train* q)
{
	int i;
	
	for(i=q->front; i < q->back; i++)
		printf("%d", q->store[i]);
 
}
void print_stack(struct station* s)
{
      int i; // index used in for loop
    
    // loop through stack from top to bottom, printing them out as we go
    for(i = 0; i < s->top; i++)
        print_queue(s->store);
;
       
}
int isQueueEmpty(struct train* q)// checks to see if the queue is empty
{
	return q->count<2;//because the queue has to have 3 space in it at a minimium
}
int dequeue(struct train* q)
{
    int rval = q->store[q->front];  // value of the integer at the front of the queue
 
    
  
    q->front = (q->front + 1) % q->size;// Move front up one position in the store array
    q->count--;
    
    return rval;// return the value that just got dequeued
 
		q->front = (q->front + 1) % q->size;
		  // this is the new line
}
void remove_car(struct train* q)//removes car from the train   
{
      if(isQueueEmpty(q))//checks to see if there are enough cars to allow the car to be removed
      {
            printf("There is only one car on the train.\n");
            
      }
      else
      {
            int rval=dequeue(q);//returns the value of the car removed
            printf("Car %d has been removed!\n", rval);
      }
}
 
 
void expandqueue(struct train* q)
{
    int i; // used in the for loop below to copy data from old store array to new one
    int* oldstore = q->store; // pointer to the store array
    
    // now, store will point to an array that is twice the size of the old one
    q->store = calloc(q->size * 2, sizeof(int));
    
    // copy the values in the queue from the old store array to the new one
    for(i = 0; i < q->size; i++)
    {
        q->store[i] = oldstore[(i+q->front) % q->size];
    }
   // q->front = 0; // the values from the old array are copied into the beginning of the new array
    //q->back = q->size; // there are q->size elements in the array so that's where back will point
    //q->size = q->size * 2; // the size of the store array has doubled
    free(oldstore); // always free memory that isn't being used
}
 
int add_car(struct train* q, int car)//adds a car to the queue and makes the queue larger is it needs to be
{
    //int data;
		
	if(!AreThereAtLeastTwoEmptySlotInTheQueue(q))
    {
        expandqueue(q);
    }    
	// put the new data into the back of the queue
    q->store[q->back] = car;
	
		//int data = add_car(q);
		//return q;
 
    // Move back up one position in the store array
    // The % (modulus) operator is used to ensure that back does not exceed the size
    //   of the array.
    // Keep in mind that we could loop around in the store array if front > back.
    q->back = (q->back + 1) % q->size;
	q->count++;
		
    
    return q;
}
 
int main(void)//main function
{
	FILE *fp;
    char fname[32];	
	int i, n;
	char action[20];
	struct station* s;
	struct train* q;
	int num_cars, rval, data, car;
	
 
	printf("Welcome to Bob's Train Station\n");
	printf("What is the name of the input file?\n");
	scanf("%s", fname);
 
	fp = fopen(fname, "r");
	if (fp == NULL)
		printf("ERROR");
	
	printf("Here is the output!:\n");
	
	fscanf(fp, "%d", &n);
	s=new_station(10);
	for(i=0; i<n; i++)
	{
		fscanf(fp,"%s", action);
		if(strcmp(action,"new_train")==0)
		{
			//printf("******");
			fscanf(fp, "%d", &num_cars);
			q=new_train(num_cars);				
			add_train(s, q, num_cars, fp);
		}
		else if(strcmp(action, "remove_car")==0)
		{
			//printf("---------");
			remove_car(q);
		}
		else if(strcmp(action, "add_car")==0)
		{
			//printf("add_car\n");
			fscanf(fp, "%d", &car);
			add_car(q, car);
		}
		else if(strcmp(action, "train_departs")==0)
		{
			print_stack(s);
				printf("Train Departed:\n");
			//place funtion here
		}
	}
	fclose(fp);
		
	system("PAUSE");
	return 0;
}

Open in new window

0
 
LVL 13

Expert Comment

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

(more coming)
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793556
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
0
 

Author Comment

by:mikeregas
ID: 22793571
that is what I got
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793581
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)
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793584
Actually, I need to debug for a couple of minutes.
0
 

Author Comment

by:mikeregas
ID: 22793590
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.
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793617
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?
0
 

Author Comment

by:mikeregas
ID: 22793639
That is what I have
where do the numbers come from
0
 

Author Comment

by:mikeregas
ID: 22793643
I guess I should clarify numbers:32416
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793653
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.
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793687
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?
0
 

Author Comment

by:mikeregas
ID: 22793690
ok, you are helping me out a lot, I am actually learning here, beats the hell out of my class
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793694
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");
}
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793695
>>I am actually learning here, beats the hell out of my class
That makes my heart glad!
0
 

Author Comment

by:mikeregas
ID: 22793716
why is it i--? wouldn't that go the wrong direction
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793724
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.
0
 

Author Comment

by:mikeregas
ID: 22793726
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 . .
0
 

Author Comment

by:mikeregas
ID: 22793728
>>It merely a matter of style.

I understand what you are saying
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793737
>>how come there are no train numbers

I'm not sure.  Would you post your current code, please?
0
 

Author Comment

by:mikeregas
ID: 22793749
to print out the Station empty, is that a while statement
something like this:
while (q->count)!=0
0
 

Author Comment

by:mikeregas
ID: 22793751
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

0
 
LVL 13

Expert Comment

by:josgood
ID: 22793763
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--;
                  }
            }
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793766
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
0
 

Author Comment

by:mikeregas
ID: 22793784
I see what you are saying now. You should teach this stuff, you are very patient
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793789
Thank you!
0
 

Author Comment

by:mikeregas
ID: 22793794
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.
0
 

Author Comment

by:mikeregas
ID: 22793800
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
0
 

Author Comment

by:mikeregas
ID: 22793807
the stacks loops through till it is empty right
0
 
LVL 13

Expert Comment

by:josgood
ID: 22793809
>>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