I'm new here. I started software engineering and I have no knowledge of the C language. I did the adding part to the queue, but I cannot separate the foreign values entered. Can you help me with this?
I want to perform the steps in the picture
For example:
Input: E)(=89y-/u665%P
Output: EYUP
My Code
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#define max 5
int insq(char queue[max][80], int *rear, char data[80])
{
if (*rear == max -1)
return(-1);
else
{
*rear = *rear + 1;
strcpy(queue[*rear], data);
return(1);
}
}
int delq(char queue[max][80], int *front, int *rear, char data[80])
{
if(*front == *rear)
return(-1);
else
{
(*front)++;
strcpy(data, queue[*front]);
return(1);
}
}
int main()
{
char queue[max][80], data[80];
int front, rear, reply;
int ch;
front = rear = -1; //... Initialize a Queue
printf("------------------------------\n");
printf("\tMenu");
printf("\n------------------------------");
printf("\n 1. Insert String in a Queue");
printf("\n 2. Delete String from a Queue");
printf("\n 3. Exit");
printf("\n------------------------------\n");
while(1)
{
printf("Choose operation : ");
scanf("%d", &ch);
switch(ch)
{
case 1 : // insert
printf("\nEnter Something : ");
scanf("%s",data);
reply = insq(queue, &rear, data);
if(reply == -1 )
printf("\nQueue is Full \n");
else
printf("\n'%s' is inserted in queue.\n\n",data);
break;
case 2 : // delete
reply = delq(queue, &front, &rear, data);
if( reply == -1 )
printf("\nQueue is Empty \n");
else
printf("\nDeleted String from Queue is : %s\n", data);
printf("\n");
break;
case 3 : exit(0);
default: printf("Invalid operation \n");
}
}
return 0;
}
You have to parse char by char your string.
Test if it is an char with isalpha then do toupper and happen it to the buffer out. If not test for a blank char and copy it as it, finally just skip char.
Don't forget to add the final \0
/!\ A test if missing to check if you don't overflow out
#include <stdio.h>
#include <ctype.h>
int main() {
const char *p = "E)(=89y-/u665%P";
char out[80];
char *q = out;
while (*p) {
if (isalpha(*p)) {
*q++ = toupper(*p++);
continue;
} else if (isblank(*p)) {
*q++ = *p++;
continue;
}
p++;
}
*q= '\0';
printf("%s\n", out);
return 0;
}
You have in out "EYUP"
Related
I want to insert the data in ascending order based on the partNumber.
When the function is called in main, then the node is successfully added at the first position. But on calling the function second time, there is some problem in insertion and I am unable to figure it out. When I enter the values(in second call), I get the error
Process exited after 8.277 seconds with return value 3221225477
typedef struct part {
int partNumber;
char partName[200];
int partQuantity;
struct part *nextPart;
} Part;
Part *inventory = NULL;
void insertPart();
int
main(int argc, char *argv[])
{
insertPart();
insertPart();
insertPart();
insertPart();
return 0;
}
void
insertPart()
{
Part *tempPart,
*traversePart,
*swapPart;
int counter = 0;
traversePart = inventory;
tempPart = (Part *) malloc(sizeof(Part *));
printf("Enter the Part Number\n");
scanf("%d", &(tempPart->partNumber));
getchar();
printf("Enter the Part Name\n");
fgets(tempPart->partName, 200, stdin);
printf("Enter the Part Quantity\n");
scanf("%d", &(tempPart->partQuantity));
getchar();
if (inventory == NULL) {
inventory = tempPart;
printf("Part added at the first position.\n");
}
else {
while (traversePart->nextPart->partNumber < tempPart->partNumber) {
counter++;
traversePart = traversePart->nextPart;
if (traversePart->nextPart == NULL) {
break;
}
}
if (counter == 0) {
swapPart = inventory;
inventory = tempPart;
tempPart->nextPart = swapPart;
}
else if (traversePart->nextPart == NULL) {
traversePart->nextPart = tempPart;
}
else {
swapPart = traversePart->nextPart;
traversePart->nextPart = tempPart;
tempPart->nextPart = swapPart;
}
}
printf("Element added at position : %d", counter);
}
The problem is traversePart->nextPart->partNumber traversePart->nextPart is not referring to anything or it is not holding any of the address. When you insert first value if condition is true
if (inventory == NULL) {
inventory = tempPart;
printf("Part added at the first position.\n");
}
inventory now holding the address of tempPart but while assigning values of tempPart you never assign an address to its nextvalue and it's not there because you only inserted the first value. For the second position
else{
while(traversePart->nextPart!=NULL)
{
traversePart=traversePart->nextPart;
}
if(traversePart->partNumber < tempPart->partNumber){
//here you can verify conditions
traversePart->nextPart = tempPart
}
}
You're intermixing fgets and scanf [and getchar]. Better to use just fgets and then apply strtol for numbers [or sscanf].
You're linked list code is a bit convoluted. It can be simplified.
Here's the refactored code. I've pulled some helper functions that I had lying around to do the prompting.
And, I added list printing.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef struct part {
int partNumber;
char partName[200];
int partQuantity;
struct part *nextPart;
} Part;
Part *inventory = NULL;
void insertPart();
int getstr(char *buf,int buflen,const char *prompt);
long getnum_strtol(const char *prompt);
int
main(int argc, char **argv)
{
insertPart();
insertPart();
insertPart();
insertPart();
for (Part *cur = inventory; cur != NULL; cur = cur->nextPart)
printf("partNumber=%d partQuantity=%d partName='%s'\n",
cur->partNumber,cur->partQuantity,cur->partName);
return 0;
}
void
insertPart(void)
{
Part *tempPart;
Part *cur;
Part *prev = NULL;
int counter = 0;
#if 0
tempPart = (Part *) malloc(sizeof(Part *));
#else
tempPart = malloc(sizeof(*tempPart));
#endif
tempPart->partNumber = getnum_strtol("Enter the Part Number");
getstr(tempPart->partName,sizeof(tempPart->partName),"Enter the Part Name");
tempPart->partQuantity = getnum_strtol("Enter the Part Quantity");
tempPart->nextPart = NULL;
// find the tail/end of the list
for (cur = inventory; cur != NULL; cur = cur->nextPart) {
++counter;
// insert in sorted part order
if (cur->partNumber > tempPart->partNumber)
break;
prev = cur;
}
do {
tempPart->nextPart = cur;
// insert in the middle or end of list
if (prev != NULL) {
prev->nextPart = tempPart;
break;
}
// insert in new list or before first element of existing list
tempPart->nextPart = inventory;
inventory = tempPart;
} while (0);
printf("\nElement added at position : %d\n", counter);
}
// getstr -- get a string with prompt
// RETURNS: length or (<0 -> error)
int
getstr(char *buf,int buflen,const char *prompt)
{
char *cp;
int ret = 0;
// NOTE: usage of the error codes in errno.h is arbitrary
while (ret <= 0) {
// ensure buffer has enough space
if (buflen < 2) {
ret = -ENOMEM;
break;
}
// output prompt
if (prompt != NULL) {
printf("%s: ",prompt);
fflush(stdout);
}
// get a line
cp = fgets(buf,buflen,stdin);
// EOF
if (cp == NULL) {
ret = -ENODATA;
break;
}
// get buffer length
ret = strlen(buf);
// empty string
if (ret <= 0)
continue;
// point to last char
cp = &buf[ret - 1];
// ensure we got a newline -- if not, fgets had to chop the line (i.e.)
// the line is too long to fit in the buffer
if (*cp != '\n') {
ret = -ENOSPC;
break;
}
// strip the newline -- we are done
*cp = 0;
--ret;
}
return ret;
}
// getnum_strtol -- get number using strtol
long
getnum_strtol(const char *prompt)
{
int len;
int readflg = 1;
char *cp;
char buf[100];
long num = 0;
while (readflg) {
len = getstr(buf,sizeof(buf),prompt);
if (len < 0)
exit(1);
num = strtol(buf,&cp,10);
// ensure we got a least one digit
if (cp <= buf)
continue;
switch (*cp) {
case ' ':
case '\t':
case 0:
readflg = 0;
break;
default:
printf("getnum_strtol: not a valid number -- buffer '%s', invalid '%s'\n",
buf,cp);
break;
}
}
return num;
}
Here's the input file I used to test:
37
Hex Bolt
12
28
Machine Screw
6
23
Brad Nail
1000
27
Lock Nut
300
Here's the program output:
Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 0
Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 1
Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 1
Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 2
partNumber=23 partQuantity=1000 partName='Brad Nail'
partNumber=27 partQuantity=300 partName='Lock Nut'
partNumber=28 partQuantity=6 partName='Machine Screw'
partNumber=37 partQuantity=12 partName='Hex Bolt'
I am trying to sort the following structure. I am using the qsort to order the books according to date publish in order of the newest first. I completely don't understand why the pointer can't access the date-published element.
#include <string.h>
#include <stdlib.h>
#include "problem5.h"
int int_cmp(const void *a, const void *b)
{
//const int *ia = (const int *)a;
//const int *ib = (const int *)b;
//return *ia - *ib;
return (*(int*)a - *(int*)b);
}
int main()
{
struct book* books = NULL; // no books at all initially so we initialize to NULL
// so we can simply use realloc
int numberofbooks = 0;
int programend = 0;
while (programend == 0)
{
printf("1. Add Book\n");
printf("2. View Books\n");
printf("3. Quit\n");
int command;
int i, j;
scanf("%d", &command);
if (command == 1)
{
getchar(); // consume Enter key (due su scanf)
// allocate memory for one more book
books = realloc(books, sizeof(struct book) * (numberofbooks + 1));
printf("Enter Name\n");
gets(books[numberofbooks].name);
printf("Enter Author\n");
gets(books[numberofbooks].author);
printf("Enter Year Published\n");
scanf("%d", &books[numberofbooks].year_published);
numberofbooks++; // increment number of books
printf(books.year_published);
}
else if (command == 2)
{
qsort(books->year_published, numberofbooks, sizeof(int), int_cmp);
for (i = 0; i < numberofbooks; i++)
{
printf("%d - %s by %s\n", books[i].year_published, books[i].name, books[i].author);
}
}
else if (command == 3)
{
programend = 1;
}
//else if and the else will prevent infinite loop when the user enters invalid choice in the beginning.
else if (command != 1 || command != 2 || command != 3)
{
printf("Invalid choice!\n");
}
else {return 0;}
}
free(books);
return 0;
}
I think the problem is the pointer in the qsort() but I don't know how to correct that. I tried using qsort(books, numberofbooks, sizeof(int), int_cmp); but the books weren't ordered as expected.
Here is an example of a multikey sort:
int
cmp_multikey(const void *a,const void *b)
{
const struct book *booka = a;
const struct book *bookb = b;
int cmp;
do {
// sort by year published
cmp = booka->year_published - bookb->year_published;
if (cmp)
break;
// sort by author
cmp = strcmp(booka->author,bookb->author);
if (cmp)
break;
// sort by title
cmp = strcmp(booka->name,bookb->name);
if (cmp)
break;
} while (0);
return cmp;
}
Invoke with:
qsort(books,numberofbooks,sizeof(struct book),cmp_multikey);
Some other tips ...
[As others have mentioned] Never use gets. Use a switch/case instead of an if/else ladder.
Try to avoid intermixing scanf and fgets.
Personally, I prefer to [always] use fgets. Here is a [safe] replacement for gets and a replacment for scanf("%d",&num);:
int
getstr(const char *prompt,char *buf,int buflen)
{
char *cp;
printf("%s",prompt);
fflush(stdout);
cp = fgets(buf,buflen,stdin);
if (cp == NULL) {
fprintf(stderr,"unexpected EOF\n");
exit(1);
}
// find newline
cp = strchr(buf,'\n');
// ensure we had enough space
if (cp == NULL) {
fprintf(stderr,"response too large for buffer\n");
exit(1);
}
// strip newline
*cp = 0;
}
int
getnum(const char *prompt)
{
char buf[1000];
int num;
getstr(prompt,buf,sizeof(buf));
num = atoi(buf);
return num;
}
I'm currently working on a program that is suppose to read information from a text-file. The text-file contains a song list and I have created a struct that should be able to hold each song in a song list in my program.
I have divided the program in different files and they look something like this.
main.c
#include "FuncDek.h"
#include <locale.h>
#include <crtdbg.h>
int main()
{
//For swedish and check memory leak
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
setlocale(LC_ALL, "swedish");
//Create with starting size of 5
Song *ptr = (Song *)malloc(sizeof(Song) * 4);
int menuChoice = 0;
int nrOfSongs = 0;
//Read from file
readFromFile(ptr, &nrOfSongs);
system("pause");
do
{
system("cls");
menuChoice = menu();
switch (menuChoice)
{
case 1:
addSong(ptr, &nrOfSongs);
break;
case 2:
showList(ptr, nrOfSongs);
break;
case 0:
break;
default:
printf("\nFelaktigt val, försök igen\n");
system("pause");
break;
}
} while (menuChoice != 0);
free(ptr);
system("pause");
return 0;
}
FuncDek.h
#ifndef FUNCDEK
#define FUNCDEK
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char title[25];
char artist[25];
char year[4];
} Song;
int menu();
void addSong(Song *ptr, int *nrOfSongs);
void showList(Song *ptr, int nrOfSongs);
void readFromFile(Song *ptr, int *nrOfSongs);
#endif
and finally the FuncDek.c
#include "FuncDek.h"
#pragma warning(disable: 4996)
//Print all from list
void showList(Song *ptr, int nrOfSongs)
{
system("cls");
printf("Låtlista\n");
printf("-------------------------------\n");
for (int i = 0; i < nrOfSongs; i++)
{
printf("Title: %s", ptr[i].title);
printf("Artist: %s", ptr[i].artist);
printf("År: %s \n\n", ptr[i].year);
}
system("pause");
}
//Read from file
void readFromFile(Song *ptr, int *nrOfSongs)
{
FILE *fileOpen;
fileOpen = fopen("song.txt", "r+");
if (fileOpen == NULL)
{
printf("Something went wrong. Could't open file\n");
}
char line[100];
int counter = 0;
int nrOfSongsInList = 0;
/*Read all information to line*/
while (fgets(line, sizeof(line), fileOpen) != NULL)
{
if (counter == 0)
{
nrOfSongsInList = line[0] - '0';
counter++;
}
else if (counter % 2 == 1 && counter == 1)
{
strcpy(ptr[*nrOfSongs].title, line);
counter++;
}
else if (counter % 2 == 0)
{
strcpy(ptr[*nrOfSongs].artist, line);
counter++;
}
else if (counter % 3 == 0)
{
strcpy(ptr[*nrOfSongs].year, line);
counter = 1;
*nrOfSongs += 1;
}
}
fclose(fileOpen);
}
I can now read my text-file and store my songs in my stong struct and I have allocated memory for it.
My problems occure when I'm trying to use the showList function. I can print out the ptr[i].artist and ptr[i].title correct, but for some reason when I print the ptr[i].year it show the year + the title of the next song in the list.
My text-file looks like this and each row is ended with a '\n'.
4
Mr Tambourine Man
Bob Dylan
1965
Dead Ringer for Love
Meat Loaf
1981
Euphoria
Loreen
2012
Love Me Now
John Legend
2016
I can't understand why it prints out more than the year. I noticed that if I make the year array in my struct the same size as the other 2, the problem goes away. But I want to understand.
When I debugg in VS it says that it's stored the right values in the year arr.
Anyone know what I might have missed?
So i need to write and read to and from a binary file, but cant seem to do it, and when using readFromFile, the program crashes. I need help write to binary file, and then reading from it and resuming my work later after turning off the program.I have no idea what i am doing wrong, and i have googled for a long time now, but with no results. Here is the code of my program:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char *subjName;
char *lectName;
char *lectSurname;
int credits;
int num_students;
}Subject;
typedef struct{
Subject **subjs;
int num_subjs;
}Subjects;
int numOfSubjs=0;
void listInput();
void listEdit();
void listDelete();
void listPrint();
int userChoice(int select);
int enterNumber(char *name);
void saveToFile(Subjects *subjects);
void readFromFile(Subjects *subjects);
int main() {
Subjects *subjects = malloc(sizeof(Subjects));
subjects->num_subjs = 0;
subjects->subjs = NULL;
readFromFile(subjects);
int r=1;
while(r!=0){
int select=userChoice(select);
switch(select){
case 1:
listPrint(subjects);
break;
case 2:
listInput(&subjects);
break;
case 3:
listDelete(subjects);
break;
case 4:
listEdit(subjects);
break;
case 0:
r=0;
break;
}
}
saveToFile(subjects);
return 0;
}
int userChoice(int select){ // menu options
int choice,input=0;
printf("(1). View all the data\n");
printf("(2). Enter new data\n");
printf("(3). Delete data\n");
printf("(4). Edit data\n");
printf("(0). Exit\n");
printf("-----------------------------\n");
while(input!=1){
choice = enterNumber("menu");
if(choice>4 || choice<0){
printf("Invalid input \n");
}
else
input = 1;
}
return choice;
}
void listPrint(Subjects *subjects){ // print data
int i;
for(i=0; i< numOfSubjs; i++){
printf("%d, %s, %s, %s, %d, %d\n",i+1, subjects->subjs[i]->subjName, subjects->subjs[i]->lectName, subjects->subjs[i]->lectSurname, subjects->subjs[i]->credits, subjects->subjs[i]->num_students);
}
printf("Number of entries: %d \n", numOfSubjs);
}
char *getln() //dynamically allocate input string
{
char *line = NULL, *tmp = NULL;
size_t size = 0, index = 0;
int ch = 1;
while (ch) {
ch = getc(stdin);
if (ch == '\n')
ch = 0;
if (size <= index) {
size += 1;
tmp = realloc(line, size);
if (!tmp) {
free(line);
line = NULL;
break;
}
line = tmp;
}
line[index++] = ch;
}
return line;
}
void saveToFile(Subjects *subjects){
FILE *data;
data = fopen("data.bin","wb");
printf("%s", subjects->subjs[0]);
for(int i=0; i<numOfSubjs; i++){
fwrite(&subjects->subjs[i],sizeof(Subject*),1,data);
}
fclose(data);
}
void readFromFile(Subjects *subjects){
FILE *data;
int i=0;
data = fopen("data.bin","rb");
while(!feof(data))
{
fread(&subjects->subjs[i],sizeof(Subject*),1,data);
i++;
}
fclose(data);
}
int isText(char *str,char *name){ // check if is text
for(int i = 0; i < strlen(str);i++){
if((str[i]<'A' || str[i]>'z') && str[i]!=' '){
printf("Error, %s must be a text \n",name);
return 0;
}
}
return 1;
}
int enterNumber(char *name){ // enter number and check if is number
int input=0, crash=0, num=0;
while(input!=1)
{
crash=0;
printf("Enter the number of %s\n", name);
scanf("%d", &num);
while(getchar()!='\n')
{
crash++;
}
if(crash>0 || num<0)
printf("Error, enter a not negative number of %s\n", name);
else if(crash==0)
input=1;
}
return num;
}
void listInput(Subjects **p_subjects){ // input new data
Subject *new_subj = malloc(sizeof(Subject));
new_subj->subjName = NULL;
new_subj->lectName = NULL;
new_subj->lectSurname = NULL;
new_subj->credits = 0;
new_subj->num_students = 0;
do{
printf("Enter the name of the subject \n");
new_subj->subjName = getln();
}while(!isText(new_subj->subjName,"Subject name"));
do{
printf("Enter the name of the lecturer \n");
new_subj->lectName = getln();
new_subj->lectName[0] &= '_';
}while(!isText(new_subj->lectName,"Lecturer's name"));
do{
printf("Enter the surname of the lecturer\n");
new_subj->lectSurname = getln();
new_subj->lectSurname[0] &= '_'; //Convert to uppercase if lowercase
}while(!isText(new_subj->lectSurname,"Lecturer's name"));
new_subj->credits = enterNumber("credits");
new_subj->num_students = enterNumber("students");
(*p_subjects)->subjs = realloc((*p_subjects)->subjs,sizeof(Subject*)*(++(*p_subjects)->num_subjs));
(*p_subjects)->subjs[(*p_subjects)->num_subjs-1] = new_subj;
numOfSubjs++;
printf("Added a new entry.\n\n");
}
void listDelete(Subjects *subjects){ // delete entries
int del;
if(numOfSubjs==0)
printf("Number of entries is 0, can't delete anything\n");
else{
printf("Enter 0 to exit. Number of subjects : %d \n", numOfSubjs);
while(1){
del = enterNumber("entry which you would like to delete");
if(del<=numOfSubjs && del>0){
for(int i = del-1; i<numOfSubjs-1; i++){
subjects->subjs[i]=subjects->subjs[i+1];
subjects->subjs = realloc(subjects->subjs,sizeof(Subject*)*(--subjects->num_subjs));
}
numOfSubjs--;
break;
}
if(del>numOfSubjs)
printf("Error, input a number between 1 and %d (or enter 0 to exit)\n", numOfSubjs);
else
break;
}
}
}
void listEdit(Subjects *subjects){ // edit entries
int choice=0, editEntry=0, editSubj=0;
if(numOfSubjs == 0)
printf("Number of entries is 0, can't edit anthing\n");
else{
while(1){
printf("Number of entry must be between 1 and %d \n", numOfSubjs);
choice = enterNumber("entry you would like to edit.");
if(choice>0 && choice<=numOfSubjs){
while(1){
editEntry = enterNumber("what would you like to edit\n 1 - Subject name\n 2 - Lecturer's name\n 3 - Lecturer's surname\n 4 - Number of credits\n 5 - Number of students");
if(editEntry>0 && editEntry <=5){
switch(editEntry){
case 1:
do{
printf("Enter the name of the subject \n");
subjects->subjs[choice-1]->subjName = getln();
}while(!isText(subjects->subjs[choice-1]->subjName,"Subject name"));
break;
case 2:
do{
printf("Enter Lecturer's name \n");
subjects->subjs[choice-1]->lectName = getln();
}while(!isText(subjects->subjs[choice-1]->lectName,"Lecturer's name"));
break;
case 3:
do{
printf("Enter Lecturer's surname \n");
subjects->subjs[choice-1]->lectSurname = getln();
}while(!isText(subjects->subjs[choice-1]->lectSurname,"Lecturer's surname"));
break;
case 4:
subjects->subjs[choice-1]->credits = enterNumber("credits");
break;
case 5:
subjects->subjs[choice-1]->num_students = enterNumber("students");
break;
}
}
break;
}
}
break;
}
}
}
&subjects->subjs[i], This is Undefined behavior. Accessing garbage value. You need to properly initialize it proper memory address. You ddin't do it anywhere.
(*subjects).subjs or subjects->subjs -> This is not pointing anywhere. It is NULL.
Also here you don't need the double pointer. A single pointer would do the thing you want to do.
typedef struct{
Subject *subjs;
int num_subjs;
}Subjects;
For single pointer this would be like
Subjects *subjects = malloc(sizeof(Subjects));
subjects->num_subjs = 10;
subjects->subjs = malloc(subjects->num_subjs * sizeof Subject);
subjects->subjs[0].subjName = malloc(40);
Each of the malloc should be checked with it's return Value. If it's NULL then it would be error to proceed further or access it.
And free() it accordingly when you are done working with it.
Some basic things:-
typedef struct{
Subject *subjs;
int num_subjs;
}Subjects;
Now let's look a bit in the code.
Op asked why OP should initialize and isn;t subjects->num_subjs = 0;
subjects->subjs = NULL; not enough?
A pointer is a variable that is supposed to hold address. here Subject* will hold the address of the variables of type Subject.
Now here initially you initialized it.
You have allocated a memory and assigned it's address to the Subject* variable subjects.
Now let's see what else you do.
subjects->num_subjs = 0;
subjects->subjs = NULL;
You initialized it. And then you try to access it(subjects->subjs[i]). Can you tell me where it points to? (subject->subjs)?
Answer is nope. It is pointing to nowhere. It contains NULL value now. Don't you think you should tell it how many subject you want to hold and allocate accordingly? Yes you should and that's what I did precisely in the example shown.
Whenever you have a pointer variable ask yourself what it contains - and if the value is something you know about, not some random garbage value.
Can someone help me making a queue program. I want to set the array[0] to be array[1] just in display but in real I am adding value at array[0]. I got how to run the add function to it, but I can't do the view and delete command that will view from ex. array[0] to array[4], when displayed array[1] to array[5] with the value inserted.
#include <stdio.h>
#include <stdlib.h>
#define p printf
#define s scanf
int rear = 0;
int front = 0;
int *q_array = NULL;
int size = 0;
main()
{
int num, opt;
char cont[] = { 'y' };
clrscr();
p("Queue Program\n\n");
p("Queue size: ");
s("%d", &size);
p("\n");
if(size > 0)
{
q_array = malloc(size * sizeof(int));
if(q_array == NULL)
{
p("ERROR: malloc() failed\n");
exit(2);
}
}
else
{
p("ERROR: size should be positive integer\n");
exit(1);
}
while((cont[0] == 'y') || (cont[0] == 'Y'))
{
clrscr();
p("Queue Program");
p("\n\nQueue size: %d\n\n", size);
p("MAIN MENU\n1. Add\n2. Delete\n3. View");
p("\n\nYour choice: ");
s("%d", &opt);
p("\n");
switch(opt) {
case 1:
if(rear==size)
{
p("You can't add more data");
}
else
{
p("Enter data for Queue[%d]: ", rear+1);
s("%d", &num);
add(num);
}
break;
case 2:
delt();
break;
case 3:
view();
break;
}
p("\n\nDo you want to continue? (Y\/N)");
s("%s", &cont[0]);
}
}
add(int a)
{
q_array[rear]=a;
rear++;
}
delt()
{
if(front==rear)
{
p("Queue Empty");
}
else
{
p("Queue[%d] = %d removed.", front, q_array[front]);
front++;
}
}
view()
{
int i;
for(i=front;i<=rear;i++)
p("\nQueue[%d] = %d", i, q_array[i]);
}
One serious problem here is
char cont[] = { 'y' };
...
s("%s", &cont[0]);
You've only reserved one byte but scanf will write at least 2 bytes, meaning that you are going to have a buffer overflow and then the overall behaviour is unpredictable. If you want to read a single character then use"%c" as a pattern but the problem here is that characters will be in the buffer for the next read, so you are going to have to clear the buffer.
It's much easier to do:
char line[1024];
fgets(line, sizeof line, stdin);
if(line[strlen(line)-1] == '\n')
line[strlen(line)-1] = 0;
if(strcmp(line, "Y") == 0 || strcmp(line, "y")==0)
It's a little more code but it's safer this way.
There are many queues, there are fifo, lifo, and depending on it you choose how to build it
When dealing with queues, it's better to use function names like push, pop and top because they are widely used among other programmers and queue libraries. Use
these names instead.
In your case, instead if remembering with front and rear you should use
memmove instead and use a variable len to count the current number of
elements in the node. Once you've popped one element, you gained new space for
more elements.
Also, try to use fewer global variables and more encapsulation: (in my example I am
not going to care about malloc returning NULL, I want to keep it short)
#include <string.h> /* for size_t */
typefed struct {
size_z len;
size_z max_size;
int *data;
} queue;
void queue_init(queue *q, size_t max_size)
{
q->len = 0;
q->max_size = max_size;
q->data = malloc(max_size * sizeof *(q->data));
/* this is a good trick!
* If you need to change the datatype of 'data',
* you only need to change the definition of it.
* This code is valid for any type */
}
int push(queue *q, int data)
{
if(q->len == q->max_size)
return 0; /* not enough space */
q->data[q->len++] = data;
return 1;
}
int top(queue *q, int *data)
{
if(q->len == 0)
return 0; /* no elements in the queue */
*data = q->data[0];
return 1;
}
int pop(queue *q, int *data)
{
if(top(q, data) == 0)
return 0;
memmove(q->data, q->data + sizeof *(q->data), q->len--);
return 1;
}
BTW:
#define p printf
#define s scanf
Just like Daniel Fischer said, this is ugly; don't do that.