re-prompt user after invalid input in c - c

I'm writing this program in c where I need to re-prompt the user after an invalid input. I came to a solution only to discover that if the user enters another invalid input after the re-prompt then it continues. Can someone please show me a better solution to this? I'll show you what I had anyway:
#include <stdio.h>
#include <ctype.h>
main()
{
int ctr; // loop counter
int custID[10] = {1, 3, 5, 9, 10, // ID array
6, 4, 7, 8, 2};
double custBal[10] = {153.56, 1300.45, 684.45, 990.45, 45.54, // Balance array
1100.34, 594.45, 1340.45, 1000.00, 1134.00};
int IDsearch; // For interaction
int found = 0; // Search criteria
int inner, outer, tempID, didSwap; // For sorting the arrays
double tempBal;
char ans;
/* Firs step: Sort the arrays for efficiency */
for(outer = 0; outer < 9; outer++) // <9 and not <10, because 9 numbers will be bubble sorted
{ // the highest (10th) will remain at the bottom
didSwap = 0; // Turns one after the arrays sort
for(inner = outer; inner < 10; inner++)
{
if(custID[inner] < custID[outer]) // Ascending sort
{
tempID = custID[inner]; // Must include both,
tempBal = custBal[inner]; // otherwise the arrays wont be linked
custID[inner] = custID[outer];
custBal[inner] = custBal[outer];
custID[outer] = tempID;
custBal[outer] = tempBal;
didSwap = 1; // Flag that a swap took place
}
}
if(didSwap == 0)
{
break;
}
}
/* Second step: Interacting with the program */
printf("***Customer Balance Search***\n");
do
{
printf("Which ID number do you want to check?\n");
scanf(" %d", &IDsearch);
for(ctr = 0; ctr < 10; ctr++)
{
if(IDsearch == custID[ctr])
{
found = 1;
break;
}
}
if(found)
{
if(custBal[ctr] < 1000)
{
printf("\nCustomer #%d has a balance of $%.2f.\n", custID[ctr], custBal[ctr]);
printf("Credit is good!\n");
}
else
{
printf("\nCustomer #%d has a balance of %.2f.\n", custID[ctr], custBal[ctr]);
printf("Credit is bad! No more credit!\n");
}
}
else
{
printf("\nCustomer #%d was not found!\n", IDsearch);
printf("Please enter a correct ID number!\n\n");
continue;
}
printf("\nDo you want to search another ID number?\n");
printf("Enter (Y)es or (N)o\n");
scanf(" %c", &ans);
ans = toupper(ans);
}
while((found != 1) || (ans == 'Y' && ans != 'N'));
printf("\nExiting...\n\n");
return (0);
}

Please reset found
do {
found = 0;
// ...
at the start of the do-while loop. It is not enough to initialise it when defined.

Related

Having trouble getting this program to assign a seat and loop

Having trouble getting this code to print 1 seat then loop back to user prompt. it should loop back until the seats are filled then display first class/ecoomy full. this is the code i have so far.
int main(int argc, char** argv) {
const int firstClass[] = {1, 2, 3, 4}; //first class array list
const int economyClass[] = {5, 6, 7, 8, 9, 10, 11, 12}; //economy array list
int firstLen = 4; // first class length
int economyLen = 8; //economy class length
int userInput;
int i;
//user prompt
printf("Please type 1 for First Class\n");
printf("Please type 2 for Economy\n");
printf("Please type 0 to Quit\n");
printf("\n");
scanf("%d", &userInput); // scanning for user input
if(userInput == 1){
for(i = 0; i < 4; i++){
if(i < firstLen){
printf("Class: First Seat Number: %d\n", firstClass[i]);
}
else{
printf("First Class is Full. Next flight is tomorrow.");
}
}
}
if(userInput == 2){
for (i = 0; i < 8; i++){
if(i < economyLen){
printf("Class: Economy Seat Number: %d\n", economyClass[i]);
}
else{
printf("Economy is Full. Next flight is tomorrow.");
}
}
}
}
As you want to take input from user as long as userInput != 0, so you need to take user input within a loop.
This loop will break when userInput will be 0.
Now about printing available seat from firstClass and economyClass, you can maintain 2 variables through which you keep track of last printed seat. Just like you maintain indexing while printing values of an array.
Here's a sample code. I've given some inline comments for better understanding.
int main(int argc, char** argv) {
const int firstClass[] = {1, 2, 3, 4}; //first class array list
const int economyClass[] = {5, 6, 7, 8, 9, 10, 11, 12}; //economy array list
int firstLen = 4; // first class length
int economyLen = 8; //economy class length
int firstClassSeatNumber = 0;
int economyClassSeatNumber = 0;
int userInput;
int i;
while(true) {
//user prompt
printf("Please type 1 for First Class\n");
printf("Please type 2 for Economy\n");
printf("Please type 0 to Quit\n");
printf("\n");
scanf("%d", &userInput); // scanning for user input
if (userInput == 0) {
break; // breaking the loop as we won't take further input from user
}
if(userInput == 1) {
if (firstClassSeatNumber < firstLen) {
// if we've any seat left in first class, then we'll print it
printf("Class: First Seat Number: %d\n", firstClass[firstClassSeatNumber]);
firstClassSeatNumber++; // moving to next seat of first class
}
else {
// don't have any seat left in first class
printf("First Class is Full. Next flight is tomorrow.");
}
}
else if(userInput == 2) {
if (economyClassSeatNumber < economyLen) {
// if we've any seat left in economy class, then we'll print it
printf("Class: Economy Seat Number: %d\n", economyClass[economyClassSeatNumber]);
economyClassSeatNumber++; // moving to next seat of economy class
}
else {
// don't have any seat left in economy class
printf("Economy is Full. Next flight is tomorrow.");
}
}
}
}

No matching two dimensional string arrays for a login

I was resolving an example I see in a book about C programming. This particular problem I saw in this book was about matching a kind of 'customer code'(integer) which was okay for me. But I have troubles applying the same logic for a two dimensional string where I want to prove my login.
This is from the book, which goes fine.
/*
This program searches a sorted list of customer IDs in order to get credit totals
*/
#include <stdio.h>
int main()
{
int ctr; // Loop counter
int idSearch; // Customer to look for (the key)
int found = 0; // 1 (true) if customer is found
/* Defines the 10 elements in each of the parallel arrays */
int custID[10] = {313, 453, 502, 101, 892, 475, 792, 912, 343, 633};
float custBal[10]={0.00, 45.43, 71.23, 301.56, 9.08, 192.41, 389.00, 229.67, 18.31, 59.54};
int tempID, inner, outer, didSwap, i; // For sorting
float tempBal;
// First, sort the arrays by customer ID
for (outer=0; outer<9; outer++)
{
didSwap=0; // Becomes 1 (true) if list is not yet ordered
for (inner=outer; inner<10; inner++)
{
if (custID[inner] < custID[outer])
{
tempID = custID[inner]; // Must switch both arrays of they
tempBal = custBal[inner]; // are no longer linked
custID[inner] = custID[outer];
custBal[inner] = custBal[outer];
custID[outer] = tempID;
custBal[outer]=tempBal;
didSwap = 1; // True because a swap took place
}
}
if (didSwap == 0)
{
break;
}
}
/* Interact with the user looking to find a balance */
printf("\n\n*** Customer Balance Lookup ***\n");
printf("What is the customer number? ");
scanf(" %d", &idSearch);
// Now, look for the ID in the array
for (ctr=0; ctr<10; ctr++)
{
if (idSearch == custID[ctr]) // Do they match?
{
found = 1; // Yes, match flag is set to TRUE
break; // No need to keep looping
}
if (custID[ctr] >idSearch) // No need to keep searching
{
break;
}
}
// Once the loop has completed, the ID was either found
// (found = 1) of not
if (found)
{
if (custBal[ctr]>100)
{
printf("\n** That customer's balance is $%.2f.\n", custBal[ctr]);
printf("No additional credit.\n");
}
else // Balance is less than $100.00
{
printf("\n**The customer's credit is good!\n");
}
}
else // The ID was not found
{
printf("** You have entered an incorrect customer ID.");
printf("\n ID %3d was not found in the list.\n", idSearch);
}
return(0);
}
This is what I tried to create in order to do a login.
#include <stdio.h>
#include <string.h>
int main()
{
int ctr; // Loop counter
char userSearch[20], passSearch[10]; // to look for (the key)
int found = 0; // 1 (true) if it is found
/* Defines the 5 elements in each of the parallel arrays */
char user[5][20] = {"John", "Ivan", "Paul", "Robert", "Leo"};
char pass[5][10]={"1111", "2222", "3333", "4444", "5555"};
int inner, outer, didSwap, i; // For sorting
char tempUser, tempPass;
for (outer=0; outer<4; outer++)
{
didSwap=0; // Becomes 1 (true) if list is not yet ordered
for (inner=outer; inner<5; inner++)
{
if (user[inner] != user[outer])
{
strcpy(tempUser, user[inner]);
strcpy(tempPass, pass[inner]);
strcpy(user[inner], user[outer]);
strcpy(pass[inner], pass[outer]);
strcpy(user[outer], tempUser);
strcpy(pass[outer], tempPass);
didSwap = 1;
}
}
if (didSwap == 0)
{
break;
}
}
printf("User: ");
scanf(" %s", userSearch);
printf("Password: ");
scanf(" %s", passSearch);
for (ctr=0; ctr<5; ctr++)
{
if ((strcmp(userSearch, user[ctr])==0) && (strcmp(passSearch, pass[ctr])==0)) // Do they match?
{
found = 1;
break;
}
}
if (found)
{
printf("You entered sucessfully.");
}
else
{
printf("** You have entered an incorrect data.");
printf("\n %s was not found.\n", userSearch);
}
return(0);
}
What exactly is wrong with my last code? How can I get to make a proper login with two-dimensional string arrays? I want to put like 100 users for example, and pointing each user is not an option so I thought this way would be a good idea, with this algorithm. But not sure what is my mistake.

C seg fault - where/what?

I have this program that is supposed to handle assigning seats to passengers.
I cannot figure out what is causing my seg fault. I am using an array of structs and that may be where the problem is coming from.
I think its probably a problem with dereferencing some struct members, but I can't find where.
Here is my code:
struct seat
{
// Max Name of 32 chars
char name[32];
// Seat Number
int sNum;
// Seat taken = 1, open = 0
int taken;
};
// Function headers
void seat(struct seat plane[][10]);
void mani(struct seat plane[][10]);
void pass(int seat, char name[], int class);
int main()
{
// My airline plane is 6 seats per row, 10 rows
// Row 1/2 are First Class
// Row 3/4 are Business Class
// Init counter variables to keep track of the number
// of First Class/Business seats already taken
// also the user input var
int input, ticketin, class1 = 0, class2 = 0, class3=0, sNum, i;
char namein[32];
// Vars for pass function
char passname[32];
int passclass;
int passseat;
// Init a 2d array 6 colums 10 rows
struct seat plane[6][10];
for (i=0; i<sizeof(plane); i++)
{
plane[i]->sNum = i+1;
plane[i]->taken = 0;
}
// Begin user input loop
// Menu with 3 options:
// Display the seating chart, indicating taken seats
// Display the manifest
// Display a boarding pass - seat number, name, class
do
{
do
{
// Prompt user for ticket selection
printf("Please type 1 for \"First Class\"\n");
printf("Please type 2 for \"Business Class\"\n");
printf("Please type 3 for \"Economy Class\"\n");
scanf(" %d", &ticketin);
// Check for valid input
if (ticketin == 1)
{
// Check to make sure first class is not full
if (class1 < 12)
{
class1 += 1;
printf("First class is open!\n");
} else {
printf("First class is full, please choose another class\n");
}
} else if (ticketin == 2)
{
// Check to make sure business class is not full
if (class2 < 12)
{
class2 += 1;
printf("Business class is open!\n");
} else {
printf("Business class is full, please choose another class\n");
if (class1 < 12)
{
printf("Upgrade to First Class by entering 1");
}
}
} else if (ticketin == 3)
{
// Check to make sure business class is not full
if (class3 < 12)
{
class3 += 1;
printf("Economy class is open!\n");
} else
{
printf("Economy class is full, please choose another class\n");
if (class1 < 12)
{
printf("Upgrade to First Class by entering 1");
}
if (class2 < 12)
{
printf("Upgrade to Business Class by entering 2");
}
}
} else
{
ticketin = 4;
}
// Prompt the user for their name
printf("Please input your name:\n");
scanf(" %s", namein);
} while (ticketin == 4);
// Handle loading the new passenger into plane array
switch (ticketin)
{
case 1:
for (i=0; i<12; i)
{
if (plane[i]->taken == 0)
{
plane[i]->taken = 1;
strcpy(plane[i]->name, namein);
sNum = plane[i]->sNum;
} else
{
i++;
}
}
case 2:
for (i=12; i<24; i)
{
if (plane[i]->taken == 0)
{
plane[i]->taken = 1;
strcpy(plane[i]->name, namein);
sNum = plane[i]->sNum;
} else
{
i++;
}
}
case 3:
for (i=24; i<60; i)
{
if (plane[i]->taken == 0)
{
plane[i]->taken = 1;
strcpy(plane[i]->name, namein);
sNum = plane[i]->sNum;
} else
{
i++;
}
}
}
printf("Menu Options: \n");
printf("(1) Display the seating chart\n");
printf("(2) Display the passenger manifest\n");
printf("(3) Display a boarding pass\n");
printf("(4) Quit\n");
// Prompt user for their selection
printf("Please enter your menu selection:\n");
scanf(" %d", &input);
// Switch case handling function calls
switch (input)
{
case 1:
seat(plane);
break;
case 2:
mani(plane);
break;
case 3:
printf("Please input a seat number\n");
scanf(" %d", &passseat);
if (passseat < 12)
{
passclass = 1;
} else if (passseat < 24)
{
passclass = 2;
} else
{
passclass = 3;
}
pass(passseat, plane[passseat-1]->name, passclass);
break;
default:
printf("invalid menu option or quitting\n");
break;
}
} while (input != 4);
}
// Display seating chart function
void seat(struct seat plane[][10])
{
int i, sNum;
for (i=0; i<sizeof(plane); i++)
{
if (plane[i]->taken == 1)
{
printf("Seat %d is taken\n", i++);
} else
{
printf("Seat %d is not taken\n", i++);
}
}
}
// Display Manifest function
void mani(struct seat plane[][10])
{
int i;
for (i=0; i<sizeof(plane); i++)
{
if (plane[i]->taken == 1)
{
printf("Passenger %s in seat %d\n", plane[i]->name, i++);
}
}
}
// Display boarding pass function
void pass(int seat, char name[], int class)
{
printf("Boarding pass for %s\n", name);
printf("Seat Number: %d\n", seat);
switch (class)
{
case 1:
printf("First Class");
break;
case 2:
printf("Business Class");
break;
case 3:
printf("Economy Class");
break;
}
}
There are probably other errors, but this is the most obvious one:
for (i=0; i<sizeof(plane); i++)
{
plane[i]->sNum = i+1;
plane[i]->taken = 0;
}
sizeof(plane) is the number of bytes in the plane array. This is 10 * 6 * sizeof(struct seat), so you're writing way outside the array. If you want to know the number of elements in an array, you have to divide the size of the array by the size of an array element:
for (i=0; i<sizeof(plane)/sizeof(*plane); i++)
{
plane[i]->sNum = i+1;
plane[i]->taken = 0;
}
But your code is only initializing the first element in each row of the array.
Since it's a 2-dimensional array, you need nested loops. And you should use normal member access with . rather than pointer indirection.
for (i=0; i<sizeof(plane)/sizeof(plane[0]); i++)
{
for (int j = 0; j < sizeof(plane[i])/sizeof(plane[i][0]); j++)
{
plane[i][j].sNum = i+1;
plane[i][j].taken = 0;
}
}
You could simplify all the sizeof stuff by defining macros:
#define ROWS 6
#define COLS 10
and then using these macros in the array declaration and the for loop limits.
Similar changes need to be made in other code that loops over the plane array.

C Pointers: Exception Thrown: Read access violation

I am writing a program in C that plays the game Craps. After my first roll, when I either land the point (win) or lose, the program just ends instead of calling is_win or is_loss.
But if it calls is_win or is_loss on my first roll, everything works fine.
I'm fairly certain this has something to do with the pointer pbal. I've been getting errors in the debugger saying unable to read memory, also Exception Thrown: Read access violation. I am still fairly new to pointers so I'm assuming this is the root cause of the problem.
# include "header.h"
int print_menu(void) {
int choice = 0;
printf("\n1. Enter balance\n2. Play game\n3. Get rules\n4. End game");
printf("\nEnter which you would like to do: ");
scanf("%d", &choice);
return choice;
}
void print_rules(void) {
printf("\nFirst Roll: If your die roll adds to 7 or 11, you win.\nIf it adds to 2, 3, or 12, you immediately lose.\nIf it adds to another number, that number becomes your 'point'");
printf("\nSecond Roll: If your die roll adds to your point, you win. If it adds to 7, you lose.\nKeep rolling until you get one of these.\n\n");
}
int get_balance(balance) {
printf("\nEnter how much money you would like to add (whole dollars): ");
scanf("%d", &balance);
return balance;
}
int prompt_bet(balance) {
int bet = 0;
do {
printf("\nEnter how much you would like to bet for this game: ");
scanf("%d", &bet);
} while (bet > balance); //repeats until its false that bet>bal
return bet;
}
int roll_dice(void) {
srand((unsigned int)time(NULL));
int enter = 1;
printf("\nEnter a 0 to roll your dice: ");
scanf("%d", &enter);
int die1 = rand() % 6 + 1;
int die2 = rand() % 6 + 1;
int dice = die1 + die2;
printf("You rolled a %d and a %d, with a total of %d.\n", die1, die2, dice);
return dice;
}
int calc_first_roll(int dice, int bet, int balance, int * pbal) {
int result0 = 0;
if (dice == 7 || dice == 11) {
is_win(bet, balance, pbal);
}
else if (dice == 2 || dice == 3 || dice == 12) {
is_loss(bet, balance, pbal);
}
else {
printf("Your point is %d", dice);
int point = dice;
int done = 1;
do {
dice = roll_dice();
done = calc_other_rolls(point, dice, balance, bet, *pbal);
} while (!done);
}
return result0;
}
void is_win(int bet, int balance, int *pbal) {
/* the pointer *pbal is pointing to mainbalance. I had to pass it
through everything to get it to affect mainbal the way I wanted it to.
Think of mainbalance as the permanent memory for keeping their bets & money right,
and int balance is just a messenger that doesn't get in the way of me trying
to use a pointer on mainbalance. */
*pbal = balance + bet;
printf("You win! Your new balance is %u\n", *pbal);
}
void is_loss(int bet, int balance, int *pbal) {
*pbal = balance - bet;
printf("You lost. Your new balance is %u\n", *pbal);
}
int calc_other_rolls(int point, int dice, int balance, int bet, int *pbal) {
int done = 0;
if (dice == 7) { //Goes straight to is_l / is_w instead of looping back to calc_first
is_loss(bet, balance, *pbal);
done = 0;
}
else if (dice == point) {
is_win(bet, balance, *pbal);
done = 0;
}
else {
done = 0;
}
return done;
}
# include "header.h"
int main(void) {
int mainbalance = 0;
int choice = 0;
int *pbal = &mainbalance;
do {
choice = print_menu();
if (choice == 1) {
mainbalance = get_balance();
printf("Your balance is: %d\n", mainbalance);
choice = 8; //reprints menu
}
if (choice == 3) {
print_rules();
choice = 8;
}
if (choice == 4)
exit(1);
if (choice == 2) {
int bet = prompt_bet(mainbalance);
int dice = roll_dice();
int x = calc_first_roll(dice, bet, mainbalance, pbal);
choice = 8;
}
} while (choice > 4 || choice < 1); //keeps running code until test becomes false.
return 0;
}
In this section:
if (dice == 7) { //Goes straight to is_l / is_w instead of looping back to calc_first
is_loss(bet, balance, *pbal);
done = 0;
}
else if (dice == point) {
is_win(bet, balance, *pbal);
done = 0;
}
You're not passing is_loss and is_win the pointer, you're passing the integer value, that pbal points to. * outside of a declaration is always dereferencing.
So if calc_other_rolls gets int *pbal as an argument and you wanna pass it to another function that takes int * then you should do func(pbal) and not func(*pbal), since the second one passes the value not the pointer.
Edit: As #hollow pointed out, this gets flagged by the compiler if you enable warnings, so use them.

C - Alphabetically sorting arrays error

I'm working on a phone book assignment for my CECS class and I ran into a problem with alphabetically sorting the contacts. The program will allow me to sort up to 3 contacts, however when I try to sort more than 3, the program starts spitting out garbage variables and possibly crashing.
void Sort(phone *phonebook, int *num_entries)
{
int tracker = *num_entries;
if (tracker >= 0)
{
phone *temp = (phone*) calloc(tracker, sizeof(phone));
if (temp== NULL)
printf("\n\nOut of memory\n\n");
else
{
int i, j;
for (i = 0; i < tracker; i++)
{
for (j = i+1; j < tracker; j++)
{
//Combines first and last names into 1 name for easy comparison
strcpy(phonebook[i].totalname, phonebook[i].fName);
strcpy(phonebook[j].totalname, phonebook[j].fName);
strcat(phonebook[i].totalname, phonebook[i].lName);
strcat(phonebook[j].totalname, phonebook[j].lName);
printf("\nTotal name = %s\nTotal name = %s", phonebook[i].totalname, phonebook[j].totalname); //Done so I can verify it worked correctly
if (strcmp(phonebook[i].totalname, phonebook[j].totalname) > 0)
{
strcpy(temp[i].fName, phonebook[i].fName);
strcpy(temp[i].lName, phonebook[i].lName);
temp[i].number = phonebook[i].number;
temp[i].area = phonebook[i].area;
strcpy(phonebook[i].fName, phonebook[j].fName);
strcpy(phonebook[i].lName, phonebook[j].lName);
phonebook[i].number = phonebook[j].number;
phonebook[i].area = phonebook[j].area;
strcpy(phonebook[j].fName, temp[i].fName);
strcpy(phonebook[j].lName, temp[i].lName);
phonebook[j].number = temp[i].number;
phonebook[j].area = temp[i].area;
}
}
}
printf("\n\nSuccessfully sorted!\n\n");
}
}
else
printf("\n\nYou need people in the phone book before you can sort it.\n\n");
}
-------------------------
typedef struct PhoneBook
{
char fName[20];
char lName[20];
char totalname[40];
float number;
int area;
} phone;
Edited to add the structure. And I don't use qsort because we haven't learned about it in class and the TA's are rather strict about not using stuff we haven't learned.
void Add(phone *phonebook, int *num_entries)
{
int tracker = *num_entries;
if (tracker == 0)
{
printf("\n\nSomething's wrong here\n\n");
}
else
{
const int newSize = tracker + 1;
phone *temp = (phone*) realloc(phonebook, (newSize * sizeof(phone)));
if (temp!=NULL)
{
phonebook = temp;
}
else
phonebook = NULL;
}
if (phonebook == NULL)
printf("\n\nOut of memory, can't add more to your phonebook\n\n");
else
{
printf("\n\nEnter the first name: ");
scanf("%s", phonebook[tracker].fName);
printf("\nPlease enter the last name: ");
scanf("%s", phonebook[tracker].lName);
printf("\nPlease enter the area code: ");
scanf("%d", &phonebook[tracker].area);
printf("\nPlease enter the phone number (no dashes allowed): ");
scanf("%f", &phonebook[tracker].number);
*num_entries += 1;
printf("\nContact Added.\n\n");
}
}
Edited again to show the code to add people to the phone book (also broken). After 3-4 entries, it starts placing garbage values for entries.
int main()
{
int userInput = 8; //means exit
int num_entries = 1;
phone *phonebook = (phone*) calloc(1 , sizeof(phone));
if (phonebook == NULL)
printf("\n\nOut of memory\n\n");
else
{
do
{
system("cls");
printf("Menu: \n");
printf("1) Add a Contact\n");
printf("2) Delete a Contact\n");
printf("3) Display Phone Book\n");
printf("4) Alphabetically Sort\n");
printf("5) Find a Contact\n");
printf("6) Random Contact\n");
printf("7) Delete All\n");
printf("8) Exit\n\n");
scanf(" %d", &userInput);
switch (userInput)
{
case 1: //Add a Friend
Add(phonebook, &num_entries);
break;
case 2: //Delete a Friend
Delete(phonebook, &num_entries);
break;
case 3: //List all contacts
Display(phonebook, &num_entries);
break;
case 4:
Sort(phonebook, &num_entries);
break;
case 5:
Find(phonebook, &num_entries);
break;
case 6:
Random(phonebook, &num_entries);
break;
case 7:
DeleteAll(phonebook, &num_entries);
break;
case 8:
free(phonebook);
break;
}
system("PAUSE");
}while(userInput != 8);
}
return 0;
}
Edited to show the calls for each function
Well I can't post photos without more reputation so here's the links:
Photo 1 - Adding 3 contacts works fine: http://s980.photobucket.com/user/valondon/media/C%20Realloc%20Errors/Erroronerealloc_zpsc8228131.png.html?sort=3&o=0
Photo 2 - The phone book after the fourth contact was added: http://s980.photobucket.com/user/valondon/media/C%20Realloc%20Errors/Errorthreerealloc_zps246b76e3.png.html?sort=3&o=2
Problem is with the outer loop.
If you have say 'n' entries in the array to sort, then you have to compare the first entry of the array with remaining 'n-1' entries. After first entry is compared with all 'n-1' entries that means first entry is properly located at its location in sorted array. Now you have left with 'n-1' entries to sort. Now if you want to compare 2nd entry of the array then you have to compare that 2nd entry with remaining 'n-1-1' (only 'n-1' entries left to sort and you have taken 2nd entry to compare with rest of the entries). this goes on till the end.
In your code you can change the code like below (the loop part):
Note: I have created a temp variable of temp of structure phone.
phone temp;
for (i = 0; i < tracker - 1; i++)
{
for (j = i+1; j <= tracker - 1; j++)
{
//Combines first and last names into 1 name for easy comparison
strcpy(phonebook[i].totalname, phonebook[i].fName);
strcpy(phonebook[j].totalname, phonebook[j].fName);
strcat(phonebook[i].totalname, phonebook[i].lName);
strcat(phonebook[j].totalname, phonebook[j].lName);
printf("\nTotal name = %s\nTotal name = %s", phonebook[i].totalname, phonebook[j].totalname); //Done so I can verify it worked correctly
if (strcmp(phonebook[i].totalname, phonebook[j].totalname) > 0)
{
strcpy(temp.fName, phonebook[i].fName);
strcpy(temp.lName, phonebook[i].lName);
temp.number = phonebook[i].number;
temp.area = phonebook[i].area;
strcpy(phonebook[i].fName, phonebook[j].fName);
strcpy(phonebook[i].lName, phonebook[j].lName);
phonebook[i].number = phonebook[j].number;
phonebook[i].area = phonebook[j].area;
strcpy(phonebook[j].fName, temp.fName);
strcpy(phonebook[j].lName, temp.lName);
phonebook[j].number = temp.number;
phonebook[j].area = temp.area;
}
}
}
printf("\n\nSuccessfully sorted!\n\n");
}
The problem is with your for loops.
In your example, j is equal to i+1 in the second loop. i has a maximum value of tracker - 1, so j can be equal to tracker. This will cause you to overshoot the array, which can trash memory.
Try changing them to:
for (i = 0; i < tracker - 1; i++)
{
for (j = 0; j < tracker - i - 1; j++)
The other issue is that in your inner loop, you are using [i] and [j] to index your swaps. If you change every [i] in that loop to [j+1], you'll have a working bubble sort.
Your inner loop ends up as:
phone temp; /* I created a stack variable called temp - saves the need for allocation */
for (i = 0; i < tracker - 1; i++)
{
for (j = 0; j < tracker - i - 1; j++)
{
//Combines first and last names into 1 name for easy comparison
strcpy(phonebook[j+1].totalname, phonebook[j+1].fName);
strcpy(phonebook[j].totalname, phonebook[j].fName);
strcat(phonebook[j+1].totalname, phonebook[j+1].lName);
strcat(phonebook[j].totalname, phonebook[j].lName);
printf("\nTotal name = %s\nTotal name = %s", phonebook[j+1].totalname, phonebook[j].totalname); //Done so I can verify it worked correctly
if (strcmp(phonebook[j+1].totalname, phonebook[j].totalname) > 0)
{
strcpy(temp.fName, phonebook[j+1].fName);
strcpy(temp.lName, phonebook[j+1].lName);
temp.number = phonebook[j+1].number;
temp.area = phonebook[j+1].area;
strcpy(phonebook[j+1].fName, phonebook[j].fName);
strcpy(phonebook[j+1].lName, phonebook[j].lName);
phonebook[j+1].number = phonebook[j].number;
phonebook[j+1].area = phonebook[j].area;
strcpy(phonebook[j].fName, temp.fName);
strcpy(phonebook[j].lName, temp.lName);
phonebook[j].number = temp.number;
phonebook[j].area = temp.area;
}
}
}

Resources