C - Displaying the parts in ascending order by part number - c

I'm new here, so I have no idea if I posted this correctly. I did everything that the instructor told us to do for this program, but this last one has me stumped because we never talked about sorting in class. It says, "Modify the print() function so that it displays the parts sorted in ascending order by part number." I tried looking through the book and on the internet, but I just caused myself to become even more confused. Can anyone help me? Here's my code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define NAME_LEN 25
#define MAX_PARTS 100
struct part {
int number;
char name[NAME_LEN + 1];
int on_hand;
float price;
};
int find_part(int number, const struct part inv[], int np);
void insert(struct part inv[], int *np);
void search(const struct part inv[], int np);
void update(struct part inv[], int np);
void print(const struct part inv[], int np);
int read_line(char [], int);
/**************************************************************
* main: Prompts the user to enter an operation code, *
* then calls a function to perform the requested *
* action. Repeats until the user enters the *
* command 'q'. Prints an error message if the user *
* enters an illegal code. *
**************************************************************/
int main(void)
{
char code;
struct part inventory[MAX_PARTS];
int num_parts = 0;
for (;;)
{
printf("Enter operation code: ");
scanf(" %c", &code);
while (getchar() != '\n') /* skips to end of line */
{
;
}
switch (code)
{
case 'i':
insert(inventory, &num_parts);
break;
case 's':
search(inventory, num_parts);
break;
case 'u':
update(inventory, num_parts);
break;
case 'p':
print(inventory, num_parts);
break;
case 'q':
return 0;
default:
printf("Illegal code\n");
break;
}
printf("\n");
}
}
/************************************************************
* find_part: Looks up a part number in the inv array. *
* Returns the array index if the part number *
* is found; otherwise, returns -1. *
************************************************************/
int find_part(int number, const struct part inv[], int np)
{
int i;
for (i = 0; i < np; i++)
{
if (inv[i].number == number)
{
return i;
}
}
return -1;
}
/****************************************************************
* insert: Prompts the user for information about a new *
* part and then inserts the part into the inv *
* array. Prints an error message and returns *
* prematurely if the part already exists or the *
* array is full. *
****************************************************************/
void insert(struct part inv[], int *np)
{
int part_number;
if (*np == MAX_PARTS)
{
printf("Database is full; can't add more parts.\n");
return;
}
printf("Enter part number: ");
scanf("%d", &part_number);
if (find_part(part_number, inv, *np) >= 0)
{
printf("Part already exists.\n");
return;
}
inv[*np].number = part_number;
printf("Enter part name: ");
read_line(inv[*np].name, NAME_LEN);
printf("Enter quantity on hand: ");
scanf("%d", &inv[*np].on_hand);
printf("Enter the price of the item: ");
scanf("%f", &inv[*np].price);
(*np)++;
}
/************************************************************
* search: Prompts the user to enter a part number, then *
* looks up the part in the inv array. If the *
* part exists, prints the name and quantity on *
* hand; if not, prints an error message. *
************************************************************/
void search(const struct part inv[], int np)
{
int i, number;
printf("Enter part number: ");
scanf("%d", &number);
i = find_part(number, inv, np);
if (i >= 0)
{
printf("Part name: %s\n", inv[i].name);
printf("Quantity on hand: %d\n", inv[i].on_hand);
printf("Item Price: %.2f\n", inv[i].price);
}
else
{
printf("Part not found.\n");
}
}
/*************************************************************
* update: Prompts the user to enter a part number. *
* Prints an error message if the part can't be *
* found in the inv array; otherwise, prompts the *
* user to enter change in quantity on hand and *
* updates the array. *
*************************************************************/
void update(struct part inv[], int np)
{
int i, number, change, userChoice, changePartNum;
float changePrice;
char *changeName[] = {""};
printf("Enter part number: ");
scanf("%d", &number);
i = find_part(number, inv, np);
if (i >= 0)
{
printf("Enter your selection to edit this particular part:\n"
"\t\t Type 1 to change the Part Number\n"
"\t\t Type 2 to change the Part Name\n"
"\t\t Type 3 to change the Price\n"
"\t\t Type 4 to change the Quantity on Hand\n"
"\t\t Type 5 to exit without making changes\n\n"
"\t\t Enter your choice here: ");
scanf("%d", &userChoice);
switch ( userChoice )
{
//printf("Would you like to change the Part Number? \nType 1 for yes or 2 for no.");
//scanf("%d", &userChoice);
case 1:
printf("Enter new part number: ");
scanf("%d", &changePartNum);
inv[i].number = changePartNum;
printf("Change part num: %d\n", changePartNum);
printf("inv[i].number: %d\n", inv[i].number);
break;
//printf("Would you like to change the Part Name? \nType 1 for yes or 2 for no.");
//scanf("%d", &userChoice);
case 2:
printf("Enter new name of part: ");
scanf("%s", changeName);
printf("Change part name: %s\n", changeName);
//strcpy (*changeName, inv[i].name[NAME_LEN + 1]);
//printf("&inv[i].name[NAME_LEN + 1]: %d\n", &inv[i].name[NAME_LEN + 1]);
break;
//printf("Would you like to change the price? \nType 1 for yes or 2 for no.");
//scanf("%d", &userChoice);
case 3:
printf("Enter change in item price: ");
scanf("%f", &changePrice);
inv[i].price = changePrice;
break;
//printf("Would you like to change the quantity on hand? \nType 1 for yes or 2 for no.");
//scanf("%d", &userChoice);
case 4:
printf("Enter change in quantity on hand: ");
scanf("%d", &change);
inv[i].on_hand = change;
break;
case 5:
printf("Exiting the editor.");
break;
default:
printf("Your choice is not on the list.");
break;
}
}
else
{
printf("Part not found.\n");
}
}
/************************************************************
* print: Prints a listing of all parts in the inv array, *
* showing the part number, part name, and *
* quantity on hand. Parts are printed in the *
* order in which they were entered into the *
* array. * *
************************************************************/
void print(const struct part inv[], int np)
{
int i;
printf("Part Number Part Name "
"Quantity on Hand "
" Price\n");
for (i = 0; i < np; i++)
{
printf("%7d\t\t %-5s%31d\t%.2f\n", inv[i].number,
inv[i].name, inv[i].on_hand, inv[i].price);
}
}
/*************************************************************
* read_line: Skips leading white-space characters, then *
* reads the remainder of the input line and *
* stores it in str. Truncates the line if its *
* length exceeds n. Returns the number of *
* characters stored. *
*************************************************************/
int read_line(char str[], int n)
{
int ch = 0;
int i = 0;
while (isspace (ch = getchar()))
{
;
}
while (ch != '\n' && ch != EOF)
{
if (i < n)
{
str[i++] = ch;
}
ch = getchar();
}
str[i] = '\0';
return i;
}

If your professor allows you to use a function from the standard libary, check out C library function to do sort, which provides an answer that shows you how to use qsort(). If you're on linux, you can also get documentation on the function (and other standard library functions) by doing man qsort. If you're not on linux, check out any of the various online man pages.
If not, your professor probably expects you to do your own research. Generally the bubble sort algorithm is taught to beginners because of its simplicity. rosettacode provides pseudo-code on what a bubble sort should look like:
repeat
hasChanged := false
decrement itemCount
repeat with index from 1 to itemCount
if (item at index) > (item at (index + 1))
swap (item at index) with (item at (index + 1))
hasChanged := true
until hasChanged = false
Note that in your print function, you already have all you need, the array and its length. You demonstrated this by looping through it and printing out all the member variables. Now you just need to write the algorithm for the sort. One thing you need for the algorithm is the comparator function. You stated that you need to sort by part number. That means your comparator function will probably look like this:
int compare(struct part a, struct part b)
{
return (a.number < b.number);
}
For qsort():
qsort(inv, np, sizeof(part), compare);
In your sorting algorithm (that you should write yourself):
if (item.number at index) > (item.number at (index + 1))

Related

Why does Dereferencing a Pointer Variable in my Helper Function causes my entire program to terminate?

My Helper Function, getInput() will read the data into the array list until end of input, where they will read in the Staff ID, total number of leave allowed and the number of days of leave taken so far. It is supposed to return the number of records read through the pointer variable n. However, when I try to dereference the pointer, the program will close and I am not sure why. Thank you in advance
My Code:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 80
typedef struct {
int id; /* staff identifier */
int totalLeave; /* the total number of days of leave allowed */
int leaveTaken; /* the number of days of leave taken so far */
}leaveRecord;
// Function Prototypes
void getInput(leaveRecord list[ ], int *n);
int mayTakeLeave(leaveRecord list[ ], int id, int leave, int n);
void printList(leaveRecord list[ ], int n);
int main(){
int choice, ID, LEAVE, leaveApproval;
int recordsRead = 0;
int *ptr = recordsRead;
leaveRecord list[SIZE];
do{
printf("Please Select one of the following Options:\n");
printf("1: getInput()\n");
printf("2: mayTakeLeave()\n");
printf("3: printList()\n");
printf("4: Quit!!\n");
scanf("%d", &choice);
switch(choice){
case 1:
getInput(list, recordsRead);
printf("Temp is %d", recordsRead);
break;
case 2:
printf("Please Enter the Staff ID:\n");
scanf("%d", &ID);
printf("Please Enter the Number of Days of Leave:\n");
scanf("%d", &LEAVE);
leaveApproval = mayTakeLeave(list,ID,LEAVE, ptr);
switch(leaveApproval){
case -1:
printf("Error!! Staff Member not found!");
break;
case 0:
printf("Leave is not approved");
break;
case 1:
printf("Leave is approved");
break;
}
break;
case 3:
break;
}
}while (choice < 3);
return 0;
}
void getInput(leaveRecord list[ ], int *n){
int option = 0, temp = 0;
int userInput;
while (option == 0){
printf("Please key in the Staff Identifier:\n");
scanf("%d", &list->id);
printf("Please key in the Total Number of Days allowed:\n");
scanf("%d", &list->totalLeave);
printf("Please key in the Number of Days of Leave taken:\n");
scanf("%d", &list->leaveTaken);
printf("Please Key in 1 if you like to stop adding Records:\n");
scanf("%d", &userInput);
if(userInput == 1){
break;
}
temp += 1;
}
// Why does dereferencing a Pointer Variable kill the entire program?
*n = temp;
}
int mayTakeLeave(leaveRecord list[ ], int id, int leave, int n){
int leaveUsed = (leave + list->leaveTaken);
for(int i = 0; i < n; i += 1){
if(list->id == id){
if((leaveUsed < list->totalLeave) || (leaveUsed == list->totalLeave)){
return 1;
}
else{
return 0;
}
}
else{
return -1;
}
}
}
void printList(leaveRecord list[ ], int n){
for(int i = 0; i < n; i += 1){
printf(list);
}
}
void getInput(leaveRecord list[ ], int *n);
Here, In getInput function n is an integer type pointer variable which wants address of integer variable.
But here, getInput(list, recordsRead) you are just sending value of records read.
You have to send address of recordsRead.
getInput(list, &recordsRead)
Also in function printList you are using wrong syntax.
printf(list);
Do this :
printf("%d",list[i]);
or
printf("%d",*(list+i));

How to delete a value in a struct?

I am trying to delete a "user" from the struct on my code.
For example, this is the struct I have:
struct clients {
char name[30];
int year;
float amount;
};
And this is the two outputs I have:
Name: Victor
Birth Year: 1998
Amount: 1000.00
Name: John
Birth Year: 1996
Amount: 1500.00
What I want to do is to delete John and all his information from my struct.
I am trying to learn dynamic memmory allocation, so I used this command:
clt = (struct clients*) malloc(n * sizeof(struct clients));
In my case I wish to write a command on case 3 that delete john from the struct, but I really can't figure out how to do that, I guess maybe using realloc? But I didn't even get close to write something it would work.
Here is my entire code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct clients {
char name[30];
int year;
float amount;
};
int main() {
struct clients *clt;
int option, n, d = 0;
char name[30];
printf("Welcome, Choose an option to begin:");
do {
printf("\n1 - Create a new list;\n");
printf("2 - Find a person in the list;\n");
printf("3 - Delete a person from the list.\n");
printf("4 - End the program.\n");
scanf("%d", &option);
switch (option) {
case 1:
printf("\nType how many clients you want to register:");
scanf("%d", &n);
// allocating memory for n numbers of struct person
clt = (struct clients*) malloc(n * sizeof(struct clients));
for (int i = 0; i < n; i++) {
printf("Type the name and the birth year:");
// To access members of 1st struct person,
scanf("%s %d", (clt + i)->name, &(clt + i)->year);
printf("\nType the amount:");
scanf("%f", &(clt + i)->amount);
}
break;
case 2:
printf("Type the name you want to find:");
scanf("%s", name);
for (int i = 0; i < n; i++) {
if (strcmp(&clt[i].name, name) == 0) {
printf("\nThats the name:");
printf("\nName: %s\n", (clt + i)->name);
printf("Birth Year: %d\n", (clt + i)->year);
printf("Amount: %.2f\n", (clt + i)->amount);
d++;
}
}
if (d == 0)
printf("This name doesn't exist\n");
break;
case 3:
break;
case 4:
break;
}
} while (option != 4);
return 0;
}
You need to discard the element from its location in the list by moving the contents in the remainder of the list up , and overwriting the target element.
for(int i = 0; i < n; i++) {
if (strcmp(&clt[i].name, name)==0)
{
printf("\nThats the name:");
printf("\nName: %s\n", (clt+i)->name);
printf("Birth Year: %d\n", (clt+i)->year);
printf("Amount: %.2f\n", (clt+i)->amount);
d++; // This seems to be your sentinel value?
}
if ( 1 == d && i+1 != n ) // if the sentinel is set, but we're not off the end of the list yet
{
memcpy(clt+i, clt+i+1, sizeof( struct clients ));
}
}
n--; // reduce the list length
You could do this in one memmove call if you prefer. As #Neil says in the comments, memmove is tolerant of overlapping source and destination.
if ( 1 == d && i != n-1 ) // if the sentinel is set, but we're not off the end of the list yet
{
memmove(clt+i, clt+i+1, (n-i-1) * sizeof( struct clients ));
break; // break for i
}
You are describing almost a dynamic array such as C++'s std::vector. It is static, but it could be a dynamic array without that much extra work. You could create a container, and split n into the container's capacity and size.
struct clients_array {
size_t size, capacity;
struct clients *data;
};
Instead of having multiple pointers, one could create a struct clients_array for each list. Sample code to deal with the struct clients_array.
#include <inttypes.h>
#include <assert.h>
#include <errno.h>
/** `a` constructor with `n` spots. Returns true or false depending on whether
it could be constructed. */
static int clients_array_reserve(struct clients_array *const a,
const size_t n) {
assert(a && n);
if(n > SIZE_MAX / sizeof *a->data) return errno = ERANGE, 0;
if(!(a->data = malloc(sizeof *a->data * n))) return 0;
a->capacity = n;
a->size = 0;
return 1;
}
/** `a` destructor; call this when `a` has been successfully constructed. */
static void clients_array_(struct clients_array *const a)
{ if(a) { free(a->data); a->data = 0; a->capacity = a->size = 0; } }
/** Extract a new uninitialized entry out of constructed `a`. Returns null if
there is no more space. */
static struct clients *clients_array_new(struct clients_array *const a) {
assert(a);
return a->capacity > a->size ? a->data + a->size++ : 0;
}
/** Remove index `rm` from `a`. */
static void clients_array_delete(struct clients_array *const a,
const size_t rm) {
assert(a && rm < a->size);
memmove(a->data + rm, a->data + rm + 1,
sizeof *a->data * (a->size - rm - 1));
a->size--;
}
Then one can have different, independent arrays at once. If you want to update the code, say to allow realloc to increase the size of the object, you only need to modify the container.

Why does my program keep printing garbage values?

For some reason when i input my time , description and index and click quit to print the array that i have populated with values and strings, i get a bunch of garbage values printed instead of what i inputed, not sure what im doing wrong. any advice?
For some reason when i input my time , description and index and click quit to print the array that i have populated with values and strings, i get a bunch of garbage values printed instead of what i inputed, not sure what im doing wrong. any advice?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5
struct event //data type called event which holds time and description for events
{
int hour; //holds the hour digit between 0-23
int minute; //holds the minute digit between 0-59
char description[41];
//holds the description for the reason of the alarm
};
typedef struct event Event; //allows coder to only have to use "Event" instead of "struct event"
int InputRange(int min, int max);
Event* InputEvent(Event *newEvent);
int AddEventAtIndex(Event list[], Event e, int i);
//int InsertionSortEvent(Event list[], int *p_size, Event e);
//void DisplayEvent(Event e);
//void DisplayEventList(Event list[], int size);
//int DeleteEvent(Event list[], int i, int *p_size);
int main (void)
{
Event EventList[MAX];
Event e;
int i=0;
int eventListSize = 0;
int choice;
do
{
printf("__= Scheduler v1.0 =__\n");
printf("1. Schedule an event.\n");
printf("2. Delete an event.\n");
printf("3. Display schedule.\n");
printf("4. Save schedule.\n");
printf("5. Load schedule.\n");
printf("6. Exit\n");
switch(choice = InputRange(1, 6))
{
case 1: InputEvent( EventList );
i = AddEventAtIndex(EventList, e, i);
break;
/* case 2: pHead = deleteStudent(pHead);
break;
case 3: printf("Press 1 to search by ID or 2 to search by name: \n");
scanf("%d", &search);
if (search == 1){
searchStudentID(pHead);
}
else if (search == 2){
searchStudentlName(pHead);
}
else{
printf("Invalid selection");
}
break;
case 4: displayStudentInfo(pHead);
break;
case 5: saveStudentInfo(pHead);
break;
case 6: end(pHead);
break;*/
default: printf("Exiting Program\n\n");
}
}
while ( choice != 6 );
printf("Index #[]\tTime\tDescription");
for ( int j = 1; j < 6; j++)
{
printf("\n[%d]\n\t%d:%d \t %s", j, EventList[j].hour,
EventList[j].minute, EventList[j].description);
}
}
int InputRange(int min, int max)
{
int timenumber;
printf("Please enter a number between %d - %d\n", min, max);
scanf("%d", &timenumber);
printf("\n");
if (timenumber < min || timenumber > max)
{
printf("Invalid Entry\n");
InputRange(min, max);
}
return timenumber;
}
Event* InputEvent(Event *newEvent)
{
if (newEvent != NULL) // quality assurance:
// make sure the pointer is valid
{
printf("Enter the event time:\n");
newEvent->hour = InputRange(0, 23);
newEvent->minute = InputRange(0, 59);
printf("Enter the event description:\n");
fgetc(stdin);
fgets(newEvent->description, 41, stdin);
printf("\n");
}
return newEvent;
}
int AddEventAtIndex(Event list[], Event e, int i)
{
--i;
printf("Where in the array would you like to store this event\n");
i = InputRange(1, 5);
list[i].hour = e.hour;
list[i].minute = e.minute;
strcpy(list[i].description, e.description);
return i;
}
Why does my program keep printing garbage values?
You use non initialized data, in main you have :
Event e;
...
i = AddEventAtIndex(EventList, e, i);
where e is not initialized but used in AddEventAtIndex :
int AddEventAtIndex(Event list[], Event e, int i)
{
...
list[i].hour = e.hour;
list[i].minute = e.minute;
strcpy(list[i].description, e.description);
the behavior of strcpy with an non initialized value is undefined and can have a dramatic consequences.
Probably the call InputEvent( EventList ); must be replaced by InputEvent(&e);
In
for ( int j = 1 ; j < 6 ; j++)
{
printf("\n[%d]\n\t%d:%d \t %s", j, EventList[j].hour,
EventList[j].minute, EventList[j].description);
}
You access out of EventList when j is 5 and 6, do for instance :
for ( int j = 0 ; j < MAX ; j++)
{
printf("[%d]\t%d:%d \t %s\n", j+1, EventList[j].hour,
EventList[j].minute, EventList[j].description);
}
But you also write entries never set printing 'garbage values', more the fact to print a string non initialized has undefined effect. A way to separate entries set and not set is to initialize all the hours by 24 and to test that value in the loop to write or not the entry.
I also changed the format because the newline after the index is not compatible with printf("Index #[]\tTime\tDescription"); and it is better to put the other newline after all rather than before to flush the output line, so also change printf("Index #[]\tTime\tDescription"); by puts("Index #[]\tTime\tDescription");
MAX is not a very good name because it is more a SUP, or just rename it by SIZE
In main you do not use eventListSize
In AddEventAtIndex
--i must be done after i = InputRange(1, 5); or just do i = InputRange(1, 5) - 1; else when i values 5 list[i] is out of list so you write out of list with an undefined behavior.
So finally the parameter i is useless, remove it.
The return index is also not used in main, you use it to assign i and do not used the value of i after. AddEventAtIndex do not need to return a value.
In InputRange
You do not check the result of scanf so the value of timenumber is undefined if a non valid integer was enter and if you do not purge the input so all the next scanf to get a number will not success
Also if the value is not in the range you just call InputRange(min, max); without returning its value so you finally return the invalid value, put all in a for(;;) for instance to only return when the value is correct.
You use fgets in InputEvent, to mix it with scanf to read number is a source of problem, replace the scanf by the use of fgets then a sscanf on the read line
In InputEvent
When you do fgetc(stdin); you probably hope to bypass a newline but if the user enter characters after the number in InputRange (supposing a number was enter) fgets will read the first of them and fgets will not get the expected description. The solution is to do fgets then sscanf in InputRange as I said above allowing you to remove that fgetc
A proposal taking into account my remarks :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5
struct event //data type called event which holds time and description for events
{
int hour; //holds the hour digit between 0-23
int minute; //holds the minute digit between 0-59
char description[41]; //holds the description for the reason of the alarm
};
typedef struct event Event; //allows coder to only have to use "Event" instead of "struct event"
int InputRange(int min, int max);
Event* InputEvent(Event *newEvent);
void AddEventAtIndex(Event list[], Event e);
//int InsertionSortEvent(Event list[], int *p_size, Event e);
//void DisplayEvent(Event e);
//void DisplayEventList(Event list[], int size);
//int DeleteEvent(Event list[], int i, int *p_size);
int main (void)
{
Event EventList[MAX];
Event e;
int choice;
/* mark uset entries */
for (int i = 0; i != MAX; ++i)
EventList[i].hour = 24;
do
{
printf("__= Scheduler v1.0 =__\n");
printf("1. Schedule an event.\n");
printf("2. Delete an event.\n");
printf("3. Display schedule.\n");
printf("4. Save schedule.\n");
printf("5. Load schedule.\n");
printf("6. Exit\n");
switch(choice = InputRange(1, 6))
{
case 1:
InputEvent( &e );
AddEventAtIndex(EventList, e);
break;
/*case 2: pHead = deleteStudent(pHead);
break;
case 3: printf("Press 1 to search by ID or 2 to search by name: \n");
scanf("%d", &search);
if (search == 1){
searchStudentID(pHead);
}
else if (search == 2){
searchStudentlName(pHead);
}
else{
printf("Invalid selection");
}
break;
case 4: displayStudentInfo(pHead);
break;
case 5: saveStudentInfo(pHead);
break;
case 6: end(pHead);
break;*/
default: printf("Exiting Program\n\n");
}
}
while ( choice != 6 );
puts("Index #[]\tTime\tDescription");
for ( int j = 0 ; j < MAX ; j++)
{
if (EventList[j].hour != 24)
printf("\t[%d]\t%d:%d \t %s\n", j+1, EventList[j].hour,
EventList[j].minute, EventList[j].description);
}
}
int InputRange(int min, int max)
{
char line[32];
int timenumber;
for (;;) {
printf("Please enter a number between %d - %d\n", min, max);
if (fgets(line, sizeof(line), stdin) == NULL)
/* EOF */
exit(-1);
if ((sscanf(line, "%d", &timenumber) == 1) &&
(timenumber >= min) &&
(timenumber <= max))
return timenumber;
printf("Invalid Entry\n");
}
}
Event* InputEvent(Event *newEvent)
{
if (newEvent != NULL) // quality assurance:
// make sure the pointer is valid
{
printf("Enter the event time:\n");
newEvent->hour = InputRange(0, 23);
newEvent->minute = InputRange(0, 59);
printf("Enter the event description:\n");
fgets(newEvent->description, sizeof(newEvent->description), stdin);
printf("\n");
}
return newEvent;
}
void AddEventAtIndex(Event list[], Event e)
{
printf("Where in the array would you like to store this event\n");
int i = InputRange(1, 5) - 1;
list[i].hour = e.hour;
list[i].minute = e.minute;
strcpy(list[i].description, e.description);
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall c.c
pi#raspberrypi:/tmp $ ./a.out
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
1
Enter the event time:
Please enter a number between 0 - 23
2
Please enter a number between 0 - 59
22
Enter the event description:
descr1
Where in the array would you like to store this event
Please enter a number between 1 - 5
1
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
1
Enter the event time:
Please enter a number between 0 - 23
3
Please enter a number between 0 - 59
33
Enter the event description:
descr2
Where in the array would you like to store this event
Please enter a number between 1 - 5
4
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
12
Invalid Entry
Please enter a number between 1 - 6
6
Exiting Program
Index #[] Time Description
[1] 2:22 descr1
[4] 3:33 descr2
note the empty line in the final print, this is because the newline is part of the description, it must be remove is present in InputEvent

C programming: Input is assigned but output display shows the incorrect value

I have been trying to figure out why my code isn't working properly. I know my code below is a mess (I am a rather poor C programmer thus far). Its a work in progress. Specifically
printf("Please enter the index of the contact you wish to view. \nThis should be a positive integer\n\n");
scanf("%d", &vIndex);
fgetc(stdin);
printf("The value of vIndex is %d", &vIndex);
I find that when i run my program I might select a keyboard input of 1, meaning I am looking at my second record in my file entries.txt. The printout of vIndex however is a number much much larger, much likely the last information stored there. Running in debug however, i find that vIndex change to 1 and but prints the strange number. My entire code is below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct rec
{
int i;
float PI;
char A;
} Record;
typedef struct
{
char fname[20];
char lname[50];
char phone[15];
} Contact;
Record * arrayAlloc(int size);
char * stringAlloc(int size);
Contact * contactAlloc();
void structAlloc();
int main(void)
{
int *ptrInt;
Record * ptrRec;
int i = 0;
char * myName;
Contact * contacts;
ptrInt = (int *)malloc(sizeof(int));
int vIndex=0;
int displayMenu();
Contact * contactAlloc();
// void searchIndex();
void searchFirst();
void searchLast();
void searchPhone();
contacts = contactAlloc();
char choice;
choice = displayMenu();
while (choice !=5)\
{
if (choice == 1)
// searchIndex();
{
printf("Please enter the index of the contact you wish to view. \nThis should be a positive integer\n\n");
// fgets(vIndex, 700, stdin);
scanf("%d", &vIndex);
fgetc(stdin);
printf("The value of vIndex is %d", &vIndex);
printf("You have selected to view the %d contact.\nFirst name:\t%c. \nLast Name:\t%c. \nPhone Number:\t%c.\n\n ", &vIndex, contacts[vIndex].fname, contacts[vIndex].lname, contacts[vIndex].phone);
}
else if (choice == 2)
searchFirst();
else if (choice == 3)
searchLast();
else if (choice == 4)
searchPhone();
choice = displayMenu();
}
printf("Thank for you using this program.\n");
return 0;
}
int displayMenu()
{
int choice = 0;
while (choice!= 1 && choice != 2 && choice != 3 && choice != 4 && choice!=5)
{
printf("\nWelcome to the phone book application. Please choose from the following options:");
printf("\n\n\t 1) Search the phone book by index. \n\t 2) Search the phone book by first name. \n\t 3) Search the phone book by last name. \n\t 4) Search the phone book by phone number. \n\t 5) Quit.\n\n");
scanf("%d", &choice);
}
return choice;
}
Contact * contactAlloc()
{
FILE * fin;
int count = 0, i = 0;
char aLine[100];
Contact * ptrContact;
fin = fopen("entries.txt", "r");
if (fin != NULL)
{
while( fgets(aLine, sizeof(aLine), fin) != NULL )
{
count++;
}
fseek(fin, 0L, SEEK_SET);
count = count / 3;
ptrContact = (Contact *) calloc(count, sizeof(Contact));
count = 0;
while( fgets(aLine, sizeof(aLine), fin) != NULL )
{
if (aLine[strlen(aLine) - 1] == '\n')
{
aLine[strlen(aLine) - 1] = '\0';
}
if (i % 3 == 0)
{
strcpy(ptrContact[count].lname, aLine);
}
else if (i % 3 == 1)
{
strcpy(ptrContact[count].fname, aLine);
}
else if (i % 3 == 2)
{
strcpy(ptrContact[count].phone, aLine);
//printf("Line %d at count %d: %s\n", i, count, aLine);
count++;
}
i++;
}
//count=count*3;
printf("%d contacts loaded.\n\n", count);
fclose(fin);
}
return ptrContact;
}
/*
void searchIndex()
{
int vIndex=0;
printf("Please enter the index of the contact you wish to view. This should be a positive integer");
scanf("%d", &vIndex);
fgetc(stdin);
printf("You have selected to view the %d contact.\nFirst name:\t%c. \nLast Name:\t%c. Phone Number:\t%c.\n\n ", &vIndex, &Contact[vIndex].fname, &Contact[vIndex].lname, &Contact[vIndex].phone);
}
*/
void searchFirst()
{
}
void searchLast()
{
}
void searchPhone()
{
}
You are printing the address of vIndex instead of the value:
printf("The value of vIndex is %d", &vIndex);
Change this line to the following:
printf("The value of vIndex is %d", vIndex);

C Program - adding, removing, and printing dominos from an array of dominos

Here are the program specs:
This assignment will be to add and remove dominos from an array of dominos. Your structure will be a domino. It will hold 3 fields (used, number1 and number2).
The used field will either hold Y or N. If used is a Y, then number1 and number 2 are the two numbers for the domino. Your main function will only allocate the array
of dominos and read the option for which action to take. Actions are print, add, remove and quit (exits the program).
You must write at least the following four functions.
int getIndex();
void addDomino(Domino * d, int size);
void removeDomino(Domino * d, int offset);
void print(Domino * d, int size);
The getIndex function will get the index to be removed.
The addDomino function will find a free spot, and then read in number1 and number2 for that domino. It will also set that domino as being used (used = ā€˜Yā€™).
The removeDomino function will remove the domino at the location index. This can be done by setting the used flag for that index to ā€™Nā€™);
Problem: I am not getting the removeDomino function to work properly. It only removes one element and wont work again.
Problem: I am not getting the addDomino function to write over the removed domino index and then continue as normal. My function will only add to the end of the array.
Please Help.
Here is the program I wrote:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int number1;
int number2;
char used;
}domino;
int getIndex();
void addDomino(domino * d, int size);
void removeDomino(domino * d, int offset);
void print(domino * d, int size);
int main()
{
int size = 0;
int index = 0;
int offset = 100;
int counter = 0;
int i = 0;
char * dummy = malloc(sizeof(char));
printf("Enter the max number of dominoes: ");
scanf("%d%c", &size, dummy);
domino * d = malloc(sizeof(domino) * size);
domino current[size];
char * input = malloc(sizeof(char));
(*input) = ' ';
while((*input) != 'q')
{
printf("Enter (p) to print, (a) to add, (r) to remove, and (q) to quit: ");
scanf("%c%c", input, dummy);
switch(*input)
{
case 'p':
index = counter;
printf("Printing Dominoes\n");
for(index = 0; index < counter; index++)
{
if(current[index].used == 'y')
{
print(&current[index], index);
}
else
{
}
}
break;
case 'a':
addDomino(&current[index], index);
index++;
counter = index;
break;
case 'r':
getIndex();
removeDomino(&current[offset], offset);
break;
case 'q':
printf("All done\n");
break;
default:
break;
}
}
return 0;
}
int getIndex()
{
int offset = 0;
char dummy = ' ';
printf("Enter the index:");
scanf("%d%c", &offset, &dummy);
return offset;
}
void addDomino(domino * d, int size)
{
char * dummy = malloc(sizeof(char));
printf("Enter number 1\n:");
scanf("%d%c", &d->number1, dummy);
printf("Enter number 2\n:");
scanf("%d%c", &d->number2, dummy);
d->used = 'y';
}
void removeDomino(domino * d, int offset)
{
d->used = 'n';
}
void print(domino * d, int index)
{
printf("Domino %d (%d,%d)\n", index, d->number1, d->number2);
}
In your 'r' case, you forgot to use the return value of GetIndex.
The offset used in getIndex is local to that function and doesn't change the offset variable in your main.
if you change getIndex(); to offset = getIndex(); I think it should work correctly.

Resources