Solved

# stack of queues

Posted on 2008-10-22
612 Views
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);

}

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

{

place funtion here

}

{

place funtion here

}

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

{

place funtion here

}//*/

}

fclose(fp);

system("PAUSE");

return 0;

}
``````
0
Question by:mikeregas
• 86
• 84
• 4

LVL 45

Expert Comment

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

{
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

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

I'll look further.
0

LVL 13

Expert Comment

ID: 22782499
Would you please post the input file  you are using?
0

Author Comment

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

}

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

{

remove_car(q);

}

{

place funtion here

}

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

{

place funtion here

}//*/

}

fclose(fp);

system("PAUSE");

return 0;

}

``````
0

Author Comment

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

train_departs

train_departs

train_departs
``````
0

Author Comment

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!
``````
0

LVL 45

Expert Comment

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

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

Author Comment

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

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

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

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

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

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

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

Author Comment

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

}

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

{

remove_car(q, rval);

}

{

}

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

{

place funtion here

}//*/

}

fclose(fp);

system("PAUSE");

return 0;

}
``````
0

Author Comment

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

LVL 13

Expert Comment

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

LVL 13

Expert Comment

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

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

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

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

}

}
``````
0

Author Comment

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

}

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

{

remove_car(q, rval);

}

{

}

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

{

place funtion here

}//*/

}

fclose(fp);

system("PAUSE");

return 0;

}
``````
0

LVL 13

Expert Comment

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, "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

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);
0

Author Comment

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:

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

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

LVL 13

Expert Comment

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

Author Comment

ID: 22783114
>>You could read it before calling
>>                  remove_car(q, rval);

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

LVL 13

Expert Comment

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

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

ID: 22783143
int dequeue(struct train* q)
which appears to be coded correctly.

Just use that.
0

Author Comment

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

}

}
``````
0

LVL 13

Expert Comment

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

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

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

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

full empty queue
0

Author Comment

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

Author Comment

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

}
``````
0

LVL 13

Expert Comment

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

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

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

Author Comment

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

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

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

0

Author Comment

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

LVL 13

Expert Comment

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

Author Comment

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;

}
``````
0

Author Comment

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

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

ID: 22783251
>>I will be working on this tomorrow

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

Author Comment

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

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

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

full empty queue
0

Author Comment

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

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

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

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

LVL 13

Expert Comment

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

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

ID: 22783301
>>Do you still have
printf("Train Departed: ");

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

Author Comment

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

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

ID: 22783318
damn I feel stupid for not seeing that
0

LVL 13

Expert Comment

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

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

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;

}
``````
0

Author Comment

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

ID: 22783347
q->store[q->back] = car;
q->back = (q->back + 1) % q->size;

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

Author Comment

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

LVL 13

Expert Comment

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

ID: 22783359
Good night.
0

LVL 13

Expert Comment

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

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

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 data;

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

{

expandqueue(q);

}

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

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

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

}

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

{

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

remove_car(q);

}

{

}

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

{

printf("Train Departed:\n");

//place funtion here

}

}

fclose(fp);

system("PAUSE");

return 0;

}
``````
0

LVL 13

Expert Comment

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

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

ID: 22792339
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

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

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

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

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

Author Comment

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;

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

}
``````
0

Author Comment

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

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

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

LVL 13

Expert Comment

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:

Are we in sync?
0

Author Comment

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

LVL 13

Expert Comment

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

ID: 22792660
yes, lets get remove_car and then work on next thing
0

LVL 13

Expert Comment

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.

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

ID: 22792718
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

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

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

Author Comment

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

//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;

}
``````
0

LVL 13

Expert Comment

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

ID: 22792745

Only need one of these

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

ID: 22792748
i understand that, makes good sense
0

Author Comment

ID: 22792759
>>
Only need one of these

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

//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;

}
``````
0

LVL 13

Expert Comment

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

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

Author Comment

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

LVL 13

Expert Comment

ID: 22792782
0

Author Comment

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

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
{
if(!IsThereAtLeastTwoEmptySlotInTheQueue(q))
{
expandqueue(q);
}
}
0

Author Comment

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:
0

LVL 13

Expert Comment

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

ID: 22792836
is this a litle better looking ?

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

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

Author Comment

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;

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

LVL 13

Expert Comment

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

Author Comment

ID: 22792886
no problem
0

LVL 13

Expert Comment

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

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

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

LVL 13

Expert Comment

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

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++;

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;

}
``````
0

Author Comment

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

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

0

LVL 13

Expert Comment

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

ID: 22792987
>>car is an udelclaired identifier in the main
You need an car definition
int car;
and then
{
fscanf(fp, "%d", &car);
}
0

Author Comment

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

ID: 22793024
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

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

//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;

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

}

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

{

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

remove_car(q);

}

{

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

}

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

{

printf("Train Departed:\n");

//place funtion here

}

}

fclose(fp);

system("PAUSE");

return 0;

}
``````
0

LVL 13

Expert Comment

ID: 22793095

if(!AreThereAtLeastTwoEmptySlotsInTheQueue(q))
I used AreThereAtLeastTwoEmptySlotsInTheQueue in my example, you used IsThereAtLeastTwoEmptySlotInTheQueue

With those two changes, the code compiles.
0

LVL 13

Expert Comment

ID: 22793152
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);
}

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

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

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

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

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;

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

ID: 22793258
I had the isQueueEmpty at the end
0

Author Comment

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

Author Comment

ID: 22793274
so it is looping through the last queue right
0

LVL 13

Expert Comment

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.

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

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

Author Comment

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;

}*/
``````
0

Author Comment

ID: 22793369
that means that I need to combine the print queue and printstack
0

LVL 13

Expert Comment

ID: 22793387
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

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

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

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

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

//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;

//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);

}

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

{

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

remove_car(q);

}

{

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

}

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

{

print_stack(s);

printf("Train Departed:\n");

//place funtion here

}

}

fclose(fp);

system("PAUSE");

return 0;

}
``````
0

LVL 13

Expert Comment

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

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

ID: 22793571
that is what I got
0

LVL 13

Expert Comment

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

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

Author Comment

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

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

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

Author Comment

ID: 22793643
I guess I should clarify numbers:32416
0

LVL 13

Expert Comment

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

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

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

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

ID: 22793695
>>I am actually learning here, beats the hell out of my class
0

Author Comment

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

LVL 13

Expert Comment

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

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

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

I understand what you are saying
0

LVL 13

Expert Comment

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

0

Author Comment

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

Author Comment

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

//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;

//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);

}

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

{

remove_car(q);

}

{

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

}

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

{

print_queue(&s->store[s->top]);

}

}

fclose(fp);

system("PAUSE");

return 0;

}
``````
0

LVL 13

Expert Comment

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

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

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

LVL 13

Expert Comment

ID: 22793789
Thank you!
0

Author Comment

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

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

ID: 22793807
the stacks loops through till it is empty right
0

LVL 13

Expert Comment

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 communicate to another and raise his understanding.  It has some similarities to raising a child (although it is less).  It is so wonderful to watch your child grow and become an adult.  It is something you have created.

Creation is the most joyous act there is.
0

LVL 13

Expert Comment

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

Am I tracking with you?
0

Author Comment

ID: 22793817
>>t is so wonderful to watch your child grow and become an adult.  It is something you have created.

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

and in case I have not said it enough:

THANK YOU!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0

Author Comment

ID: 22793825
I think I understand what you are saying, as long as there are enough train_departs to match the new_train the trains will come out of the station, so 1 train_departs removes 1new_train
0

LVL 13

Accepted Solution

josgood earned 500 total points
ID: 22793838
You are very very very welcome.  I really appreciate the acknowledgement!

It is well past my bedtime and I think you are in good shape.

I have a way you can pay me back.  Sometime along, someone will need help that you can give and it may take a few hours to give that help.  Give the help needed and ask that person to pay you back in the same way.

>>1 train_departs removes 1new_train
Yes, exactly.

Have a great time with your new child.  No reason to be afraid of it.  Amateur parents deal with children all the time and everyone survives.

I'll see you around the site!

Joe
0

Author Comment

ID: 22793848
Thanks again Joe and I will do that, spend the time that someone needs to learn what I can help them with.

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

Mike
0

LVL 13

Expert Comment

ID: 22793854
>>Thanks again Joe and I will do that
Excellent!  Thank you.

Good night.

Joe
0

Author Closing Comment

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

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

### Suggested Solutions

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.