My idea is to make this program to first queue the number (start from 1001)until 10 loop.But at the same time every twice loop. i want it to delete the first number insert.Then it continue insert number after the last number insert. For example. (0) insert 1001,(1) insert 1002,(2) delete 1001,(3) insert 1003,(4) insert 1004,(5)delete 1002. This is what i imagine and the desire output. But now. When it delete it reset to the initial number.
#include <stdio.h>
#define MAX 10 /* The maximum size of the queue */
#include <stdlib.h>
void insert(int queue[], int *rear, int value)
{
if(*rear < MAX-1)
{
*rear= *rear +1;
queue[*rear] = value;
printf("\n%d queue at counter 1",value);
}
else
{
printf("\nThe queue is full can not insert a value\n");
exit(0);
}
}
void delete(int queue[], int *front, int rear, int * value)
{
if(*front == rear)
{
printf("\nThe queue is empty can not delete a value\n");
exit(0);
}
*front = *front + 1;
*value = queue[*front];
printf("\n%d left counter 1",*value);
}
int main()
{
int queue[MAX];
int iCounter,front,rear,loop=0,a,b,c;
front=rear=-1;
a=1001;
do{
printf("\n------------------------------");
printf("\n\tWelcome!!\n");
printf("\n------------------------------");
printf("\nPress which counter you prefer");
printf("\n1-Pay bill");
printf("\n2-Check up");
printf("\n3-QnA");
printf("\n------------------------------\n");
scanf(" %d",&iCounter);
loop++;
switch(iCounter)
{
case 1:
insert(queue,&rear,a);
a++;
break;
default:
printf("\nError input!");
break;
}
while(loop==2)
{
delete(queue,&front,rear,&a);
loop=0;
}
}while(rear<MAX-1);
return 0;
}
Your delete function take the address of a and writes the deleted value into it. So it will get set to the value you deleted.
You could just remove
*value = queue[*front];
and change
printf("\n%d left counter 1",*value);
to
printf("\n%d left counter 1",queue[*front]);
and also remove the whole parameter and then I think it does what you want it to do.
your delete() function pass a as pass by reference that's why you did not get what you want
delete(queue,&front,rear,&a);
For your design you should pass a as pass by value
delete(queue,&front,rear,a);
void delete(int queue[], int *front, int rear, int value)
Related
I'm doing self-study on C Programming, and I have been recommended the following C Program by my colleagues to study further, where you can enter the Name and Age and it displays and uses Insert, Delete, Display, and Exit menu options.
I'm trying to convert it to my current study stream logic scenario where I need to enter the Name, Exercise Mark 1 (up to 3), and then it computes the Average and gets displayed while employing the Insert, Delete, Display, Update (updating the scores only, not the names), Delete and Exit.
Any guidance please on how to learn this code and understand the logic, and apply it to the 2nd scenario will be much appreciated.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
//using parallel arrays as fields in the list
typedef struct list{
char name[MAX][31];
int age[MAX];
int last;
}LIST;
LIST L;//L structure is global
void save();
void retrieve();
void makenull();
void insert(char n[31],int a);
void del(char n[31]);
void display();
int locate(char n[31]);
int isfull();
int isempty();
int menu();
int main(){
char nm[31];
int ag;
makenull();
retrieve();
while(1){
switch(menu()){
case 1: system("cls");printf("Insert Mode\n");
printf("Input Name: ");scanf("%s",nm);
printf("Input Age: ");scanf("%d",&ag);insert(nm,ag);break;
case 2: system("cls");printf("Delete Mode\n");
printf("Input Name: ");scanf("%s",nm);del(nm);break;
case 3: display();break;
case 4: save();exit(0);
default: printf("\n1-4 lang!\n");system("pause");
}
}
return 0;
}
void makenull(){
L.last = -1;
}
void insert(char n[31],int a){
if (isfull()){
printf("List is full.\n");
system("pause");
}
else {
L.last++;
strcpy(L.name[L.last],n);
L.age[L.last]=a;
}
}
void del(char n[31]){
int p;
if (isempty()){
printf("List is empty.\n");
system("pause");
}
else {
p=locate(n);
if (p==-1){
printf("Not found.\n");
system("pause");
}
else{
for(int i = p;i<L.last;i++){
strcpy(L.name[i],L.name[i+1]);
L.age[i]=L.age[i+1];
}
L.last--;
printf("Successful delete operation.\n");
system("pause");
}
}
}
void display(){
int i;
system("cls");
printf(" Name Age \n");
for(i=0;i<=L.last;i++)
printf("%d.) %s %d\n",i+1,L.name[i],L.age[i]);
system("pause");
}
int locate(char n[31]){
int i;
for (i=0;i<=L.last;i++)
if(strcmp(L.name[i],n)==0)
return i;
return -1;
}
int isfull(){
if (L.last==MAX-1)
return 1;
else
return 0;
}
int isempty(){
return(L.last==-1);
}
int menu(){
int op;
system("cls");
printf("MENU\n");
printf("1. Insert\n");
printf("2. Delete\n");
printf("3. Display\n");
printf("4. Exit\n");
printf("\nSelect(1-4): ");
scanf("%d",&op);
return(op);
}
void save(){
FILE *fp;
int i;
fp=fopen("Practice4.dbf","w+");
if (fp==NULL){
printf("File Error.\n");
system("pause");
}
else{
for (i=0;i<=L.last;i++)
fprintf(fp,"%s %d\n",L.name[i],L.age[i]);
}
fclose(fp);
}
void retrieve(){
FILE *fp;
char n[31];
int i,a;
fp=fopen("Practice4.dbf","r+");
if (fp==NULL){
printf("File Error.\n");
system("pause");
}
else {
while(!feof(fp)){
fscanf(fp,"%s %d\n",n,&a);
insert(n,a);
}
}
fclose(fp);
}
Your code isn't properly formatted and there are no comments. I can't give you a direct answer with some code in it, but summing up all my comments (and of course I deleted them), this is what I've to say:
Consider this scenario-
if your .dbf has more than MAX 50 elements, then your while (!feof(fp)) inside retrieve() will keep calling insert() and insert() will keep executing its if () { } block.
You should put something like while (!feof(fp) && L.last < MAX) to prevent that situation and you'll need to further modify your code in insert(). Another thing is, this code doesn't have any update() function and scores variable. You'll need to add scores in your struct as well as there must be scores fields in your .dbf.
Now, for a moment let's say everything else is good to go in your code, then you should follow these following steps:
Declare variables
char nameInput[31];
float ex_marks[3], sum = 0, avr = 0;
in main().
Add another case 5 in your switch () block inside main() and translate and convert the following pseudocode into C code:
Read name in nameInput
locate()
if found then
3.a for i = 0 to 2
Read marks in ex_marks[i]
sum = sum + ex_marks[i]
3.b Calculate avr = sum / 3
3.c Display name and avr
else
Display name is not in the list.
exit
Also read about why is while(!feof()) always wrong?
I don't understand if both of the following definitions of a priority queue are correct:
1.
-ascending priority queue - elements are inserted arbitrarily, but after deletion, the smallest element is removed (assuming that data is an integer).
-descending priority queue - elements are inserted arbitrarily, but after deletion, the largest element is removed (assuming that data is an integer).
Examples for each:
5 15 10 -> after dequeue() -> 15 10
15 5 10 -> after dequeue() -> 5 10
2.
Every element of priority queue has a priority by which deletion is done.
There can be two cases. First, element with the highest priority is removed. Second, element with the lowest priority is removed.
Clearly, this is different from the first definition. If we assign priorities 6,3,12 to numbers 15, 10, 5, then after dequeue() operation there are two cases. If element with the lowest priority is removed, then the queue is 15,5 (10 is removed). If element with the highest priority is removed, then the queue is 15,10 (5 is removed).
Also, if element of a queue aren't numbers (strings, for example), then the first definition is useless.
Is that correct?
Question: Are both definitions correct? It seems to me that the first is only usable for numbers but even then it violates the priority from the second definition. Could someone explain this?
Here are two implementations for both definitions in C:
//1. DEFINITION//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX 6
int intArray[MAX];
int itemCount = 0;
int peek(){
return intArray[itemCount - 1];
}
bool isEmpty(){
return itemCount == 0;
}
bool isFull(){
return itemCount == MAX;
}
int size(){
return itemCount;
}
void insert(int data){
int i = 0;
if(!isFull()){
// if queue is empty, insert the data
if(itemCount == 0){
intArray[itemCount++] = data;
}else{
// start from the right end of the queue
for(i = itemCount - 1; i >= 0; i-- ){
// if data is larger, shift existing item to right end
if(data > intArray[i]){
intArray[i+1] = intArray[i];
}else{
break;
}
}
// insert the data
intArray[i+1] = data;
itemCount++;
}
}
}
int removeData(){
return intArray[--itemCount];
}
int main() {
insert(3);
insert(5);
insert(9);
insert(1);
insert(12);
int num = removeData();
printf("Element removed: %d\n",num);
return 0;
}
//2. DEFINITION//
#include<stdio.h>
#include<stdlib.h>
#define SIZE 5 /* Size of Queue */
int f=0,r=-1; /* Global declarations */
typedef struct PRQ
{
int ele;
int pr;
}PriorityQ;
PriorityQ PQ[SIZE];
PQinsert(int elem, int pre)
{
int i; /* Function for Insert operation */
if( Qfull()) printf("\n\n Overflow!!!!\n\n");
else
{
i=r;
++r;
while(PQ[i].pr >= pre && i >= 0) /* Find location for new elem */
{
PQ[i+1]=PQ[i];
i--;
}
PQ[i+1].ele=elem;
PQ[i+1].pr=pre;
}
}
PriorityQ PQdelete()
{ /* Function for Delete operation */
PriorityQ p;
if(Qempty()){ printf("\n\nUnderflow!!!!\n\n");
p.ele=-1;p.pr=-1;
return(p); }
else
{
p=PQ[f];
f=f+1;
return(p);
}
}
int Qfull()
{ /* Function to Check Queue Full */
if(r==SIZE-1) return 1;
return 0;
}
int Qempty()
{ /* Function to Check Queue Empty */
if(f > r) return 1;
return 0;
}
display()
{ /* Function to display status of Queue */
int i;
if(Qempty()) printf(" \n Empty Queue\n");
else
{
printf("Front->");
for(i=f;i<=r;i++)
printf("[%d,%d] ",PQ[i].ele,PQ[i].pr);
printf("<-Rear");
}
}
main()
{ /* Main Program */
int opn;
PriorityQ p;
do
{
printf("\n ### Priority Queue Operations(DSC order) ### \n\n");
printf("\n Press 1-Insert, 2-Delete,3-Display,4-Exit\n");
printf("\n Your option ? ");
scanf("%d",&opn);
switch(opn)
{
case 1: printf("\n\nRead the element and its Priority?");
scanf("%d%d",&p.ele,&p.pr);
PQinsert(p.ele,p.pr); break;
case 2: p=PQdelete();
if( p.ele != -1)
printf("\n\nDeleted Element is %d \n",p.ele);
break;
case 3: printf("\n\nStatus of Queue\n\n");
display(); break;
case 4: printf("\n\n Terminating \n\n"); break;
default: printf("\n\nInvalid Option !!! Try Again !! \n\n");
break;
}
printf("\n\n\n\n Press a Key to Continue . . . ");
getch();
}while(opn != 4);
}
A priority queue is a data structure holding elements (like any data structure) as well as their priority. This is your second definition.
However, in some cases, the elements actually represent their own priority. This is your first definition : sometimes, you just need to store a bunch of unordered numbers and retrieve them in order. Note that in this case, elements are not necessarily numbers. Other data types might have a property that can be used as priority.
I have a small doubly-linked list application. I want to add elements inside the list and then display the list normally. At the output i get my inserted elements allright, but after them i get a bunch of strange numbers( such as .... 28482 -20048 2817 ...... )
I believe it's a problem of space allocation.
Any help is appreciated, thanks in advance!
# include <stdio.h>
# include <conio.h>
# include <string.h>
# include <stdlib.h>
typedef struct elem {
int number;
struct elem * urm;
struct elem * prec;
}nod;
nod *prim=NULL,*ultim=NULL, *local=NULL, *p=NULL;
void insert_element(int numb){
nod *local=(nod *)malloc(sizeof(nod));
local->number = numb;
if (prim==NULL){
prim=local;
ultim=local;
}
else{
ultim->urm = local;
local->prec = ultim;
ultim=local;
}
}
void load_data()
{
int i,n;
nod *c = (nod *)malloc(sizeof(nod));
printf("\n cate elemente va avea lista?");
scanf("%d", &n);
printf("avem %d elemente", n);
for(i=1;i<=n;i++){
printf("\n number: ");
scanf("%d", &c->number);
insert_element(c->number);
}
}
void list_left_to_right()
{
nod *p = (nod*) malloc(sizeof(nod));
p=prim;
while(p){
printf("%d ", p->number);
p=p->urm;
}
printf("\n");
}
int main()
{
int op;
do{
printf("\n1.Enter some data\n");
printf("2.Display left - > right the data\n");
printf("0.Exit\n");
printf("choice : ");
scanf("%d",&op);
switch(op){
case 1: load_data(); break;
case 2: list_left_to_right(); break;
case 0: break;}
}
while (op!=0);
return 0;
}
(1) You have a memory leak in list_left_to_right():
nod *p = (nod*) malloc(sizeof(nod));
p=prim;
This leaks the block returned by malloc().
(2)
void insert_element(int numb) {
nod *local=(nod *)malloc(sizeof(nod));
local->number = numb;
// TODO: set local->urm and local->prec to NULL
if (prim==NULL) {
prim=local;
ultim=local;
OK, so the first time insert_element() is called, the new element is both the head and the tail.
Bug: You need to set the urm and prec fields to NULL. They have undefined values initially.
}
else {
ultim->urm = local;
local->prec = ultim;
ultim=local;
}
}
After that, the subsequent elements are inserted as a new tail (ultim).
Bug: But again you need to make sure that local->urm is set to NULL.
So, I wrote a program to insert a user input to a stack myself. But despite my rigorous trying, I could not insert the data correctly. It show data has been inserted, but while showing, garbage value is shown. Here is my main function:
//Stack
#include<stdio.h>
#include<stdlib.h>
#define MAXSTK 10
void push(int *, int, int *, int);
//void pop();
void show_stack();
int main()
{
int ch, ch1, stack[MAXSTK], top=-1;
do{
printf("\n <<Stack MENU>>");
printf("1. Add Element");
printf("2. Delete Element");
printf("3. Show Stack");
printf("4. Exit menu");
printf("\n Enter your choice->");
scanf("%d", &ch);
switch(ch)
{
case 1: printf("\n Enter element to add->");
scanf("%d",&ch1);
push(stack,ch1, &top, MAXSTK);
break;
/* case 2: pop();
break;*/
case 3: printf("\n The stack is->");
show_stack(stack, MAXSTK);
break;
default: printf("\n Invalid Choice!!!");
break;
}
}while(ch!=4);
return 0;
}
And here is my push function:
void push(int newstack[], int num, int *newtop, int bound)
{
*newtop=*newtop+1;
if(*newtop==0)
printf("\n Stack was Empty. New Value inserted.");
if(*newtop>(bound-1))
{
printf("\n Caution! OVERFLOW!!!");
}
newstack[*newtop]=num;
}
And here is my show function:
void show_stack(int newstack[], int bound)
{
int i;
printf("\n");
for(i=0;i<=bound;i++)
printf("%d",newstack[i]);
}
Please help me finding the error.
You are passing the array length and printing all array elements. so you see garbage value. Try to print only the inserted elements.
show_stack(stack, top);
and your function prototype should be
void show_stack(int *,int);
you increment your newtop everytime regardless of overflow. it's a bad practice. It will cause issues while popping() and show_stack().
you can do something like this to avoid it.
void push(int newstack[], int num, int *newtop, int bound)
{
// if newtop is < 0 display the message
if(*newtop<0)
printf("\n Stack was Empty. New Value inserted.");
// newtop will always point to top element. so if newtop is 9 it means your stack is full. so if newtop is >= bound-1(9) stack is full
if(*newtop>=(bound-1))
printf("\n Caution! OVERFLOW!!!");
else
{
*newtop=*newtop+1; //increment newtop
newstack[*newtop]=num; //store value in newtop
}
}
You are calling show_stack with the capacity (MAXSTK), not its actual size. Therefore it will display all elements in stack, whatever values they have. Simply calling it with top instead should fix the problem.
Another note: Your declaration of show_stack does not match the argument list of the implementation.
My function code for peek is not working? why is that? can anyone help me with my peek function?
#include<stdio.h>
#include<stdlib.h>
#define maxsize 10
int stack[maxsize];
int stacktop=0;
void instructions();
int process();
int push(int value);
int pop();
void display();
void peek();
int main()
{
process();
getch();
}
int process()
{
int val;
int choice;
do
{
instructions();
printf("Enter Your Choice: ");
scanf("%d",&choice);
switch( choice )
{
case 1:
printf("\nElement to be Pushed : ");
scanf("%d",&val);
push(val);
break;
case 2:
val=pop();
if(val!=-1)
{
printf("Popped Element : %d\n",val);
}
break;
case 3:
peek();
break;
case 4:
display();
break;
case 5:
break;
}
}while(choice !=5);
}
void instructions()
{
printf("Enter Your choice for the following process\n");
printf("\n[1]Push a Node on top of the list");
printf("\n[2]Pop a node off the list");
printf("\n[3]Peek The Top Node");
printf("\n[4]Display The Whole list");
printf("\n[5]Exit The Program\n");
}
int push(int val)
{
if(stacktop<maxsize)
{
stack[stacktop++]=val;
}
else
{
printf("Stack is full");
}
}
int pop()
{
int a;
if(stacktop>0)
{
a=stack[--stacktop];
return a;
}
}
void display()
{
int i;
i = 0;
if(stacktop>0)
{
printf("Elements are:");
while(i<stacktop)
{
printf("\n%d--\n",stack[i++]);
}
}
}
void peek()
{
printf("%d",stacktop);
}
Is it supposed to be:
printf("%d\n", stack[stacktop - 1]);
Print the contents, rather than the size of the stack?
Obviously you'd also need to bounds check to make sure you're not printing outside of the range of your stack (when it's empty)
I know this isn't Code Review, but I thought I would give you a few bits of advice.
When you call scanf, always check the result. For example, if the user enters something other than a decimal number, your code will end up putting an indeterminate value into the choice or val variables. The scanf function returns the number of items that were successfully read. If you asked for one item, and scanf returns 1, then you can rely on the value of that object:
int choice;
if (scanf("%d", &choice) != 1)
// handle error, can't rely on value of "choice"
else
// continue onwards, can rely on value of "choice"
Usually, the \n escapes go at the end of the string literal, not at the beginning. It is more common to do it this way, but it doesn't mean it should always go at the end.
printf("Enter Your choice for the following process\n\n");
printf("[1]Push a Node on top of the list\n");
printf("[2]Pop a node off the list\n");
printf("[3]Peek The Top Node\n");
For outputting simple strings, consider just using the puts function, which automatically appends the new-line character for you:
puts("Enter Your choice for the following process");
puts("");
puts("[1]Push a Node on top of the list");
puts("[2]Pop a node off the list");
puts("[3]Peek The Top Node");
Your display method is a perfect example of when to use a for loop instead of a while loop. Generally speaking, use a for loop when you know exactly how many items you have and you want to iterate over each of them:
void display()
{
int i;
puts("Elements are:");
for (i = 0; i < stacktop; i++)
printf("\n%d--\n", stack[i]);
}
To reverse the order of the stack, simply start at the top and go backwards:
void display()
{
int i;
puts("Elements are:");
for (i = stacktop - 1; i >= 0; i--)
printf("\n%d--\n", stack[i]);
}