• C

Unhandled exception at 0x011a1f35 in Reynolds Assignment 4.exe: 0xC0000005: Access violation writing location 0xccfcc8f0.

Users can enter as many records as they want and when they are done it lists the information that they have just entered. When I put everything into my addRecord function I got the unhandled exception error shown above. I don't really understand why I'm getting it.
/**************************************************************************
*FILE: Reynolds Assignment 3.cpp										  *
*PROG: Theresa Reynolds													  *
*PURP: Allows users to enter data and print the output when they are done *
**************************************************************************/
#include <ctype.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stdio.h>

struct customers
{
	int cust_id;
	char cust_name[28];
	char states[3];
	char discount;
	double balance_due;
	int order_out;
};

struct myRecords
{
	customers rec[10];
};

struct state
{
	char name[15];
	char abbr[3];
};

struct stateType
{
	state lists[51];
};

using namespace std;

int is_int(char [], char []);
void is_name(char [], char []);
void get_str(char[], char[]);
int checkState(struct myRecords*, struct stateType*, char[]);
char get_code(char[], char[]);
int get_orders(char[], char[]);
float get_bal(char[], char[]);
char get_char(char[]);
void addRecord(struct myRecords*);
void listFile(struct myRecords*);

int main()
{
	myRecords table, *point_table;
	point_table = &table;

	char cust;

	addRecord(point_table);
	cust = get_char ("Would you like to enter another return? ");
	cust = toupper(cust);

	while (cust == 'Y')
	{
		addRecord(point_table);
		cust = get_char ("Would you like to enter another return? ");
		cust = toupper(cust);
	}//end while
	
	listFile(point_table);
	return 0;

}//end of main

/*****************************
*Function to get customer id *
*****************************/
int is_int(char prompt[], char buf[])
{
	bool found = false;
	do{
		printf("\n %s",prompt);
		gets(buf);
		int i;
		int id;
		int y=0;
		for (i=0; buf[i]; i++)
		{
			if (!isdigit(buf[i]))
			{
				is_int("Please enter a customer id: ", buf);
			}	
			else
				
			{				
				id = atoi(buf);
				if(id < 998 && id > 0)
				{
					return id;
				}
				else
				{
					is_int("Please enter a customer id: ", buf);
				}
			}
		}
	} while (false);
}
/*******************************
*Function to get customer name *
*******************************/
void is_name(char prompt[], char name[])
{
	bool found = false;
	do{			
		printf("\n %s",prompt);
		gets(name);
		if (strlen(name) == 0)
		{
			is_name("Please enter customer name: ", name);
		}
	} while (false);
}
/******************************
*Binary search for  the state *
******************************/
int checkState (struct myRecords* table, struct stateType* STname, char stateABB[])
{
	static char f_time;
	f_time = 'Y';
	if (f_time == 'Y')
	{
		char buffer[50];
		FILE *fp;
		fp = fopen("STATES.DAT", "r");
		if (fp == NULL)
		{
			printf ("Error opening file! ");
		}
		 
		int counter = 0;
	
		while(!(feof(fp)))
		{
			
			fgets(STname->lists[counter].name, 20, fp);
			STname->lists[counter].name[strlen(STname->lists[counter].name)-1] = '\0';
			fgets(STname->lists[counter].abbr, 20, fp);
			STname->lists[counter].abbr[strlen(STname->lists[counter].abbr)-1] = '\0'; 
						
			++counter;
		}

		f_time == 'N';
	}
	
	
	int first=0,last = 50, middle, position=-1;
	bool found=false;
	
	while (!found && first <= last)
	{
		int Compare;
	    middle = (first + last) / 2;
		Compare = strcmp (STname->lists[middle].abbr, stateABB);
		if (Compare == 0)
		{
			found = true;
			position = middle;
		}
		else if (Compare > 0)
		{
			last = middle - 1;
		}
		else
		{      
			first = middle + 1;
		}
	}
	if (position == -1)
	{
		printf ("Not a valid state abbreviation");
		get_str("Please enter a state: ", stateABB);
	}
	else 
	{
		int y = 0;			
		stateABB = table->rec[y].states;
		y++;
	}
	
	return position;
}
/*******************************
*Function to get discount code *
*******************************/
char get_code(char prompt[], char code[])
{
	bool found = false;
	do{
		printf("\n %s", prompt);	
		gets(code);

		if (!strcmp(code, "A"))
		{
			return code[0];
		}
		else if (!strcmp(code, "B"))
		{
			return code[0];
		}
		else if (!strcmp(code, "C"))
		{
			return code[0];
		}
		else if (strlen(code) == 0)
		{
			return code[0];
		}
		else
		{
			get_code("Please enter discount code: ", code);
		}
	} while (false);
}
/************************************
*Function to get outstanding orders *
************************************/
int get_orders(char prompt[], char order[])
{
	bool found = false;
		printf("\n %s",prompt);
		gets(order);
		int i;
		int orders;
		int y=0;
		for (i=0; order[i]; i++)
		{
			if (!isdigit(order[i]))
			{
				get_orders("Please enter outstanding orders: ", order);
			}	
			else
			{				
				orders = atoi(order);
				if(orders > 0 && orders <= 30)				
				{
					return orders;
				}
				else
				{
					get_orders("Please enter outstanding orders: ", order);
				}
			}
			
		}
}
/*****************************
*Function to get balance due *
*****************************/
float get_bal(char prompt[], char bal[])
{
	bool found = false;
	do {
		printf("\n %s",prompt);
		gets(bal);
		int i;
		float balance;
		int y=0;
		for (i=0; i < strlen(bal); i++)
		{
			if (!isdigit(bal[i]))
			{
				get_bal("Please enter balance due: ", bal);
			}	
			else
			{
				balance = atof(bal);
				return balance;
			}
		}
	} while (false);
}
/**************************
*Function to add a record *
**************************/
void addRecord (struct myRecords *table)
{
	stateType STname, *point_STname;
	point_STname = &STname;

	char buf[50];
	char name[50];
	char stateABB[3];
	char code[50];
	char order[50];
	char bal[50];
	
	char string[50];
	int x;
	int y;
	for (x=0; x < 10; x++)
	{	
		if (table->rec[x].cust_id == 999)
		{
            y = x;
			x = 10;		
		}
	}
	table->rec[y].cust_id = is_int("Please enter a customer id: ", buf);
	is_name("Please enter customer name: ", table->rec[y].cust_name);
	get_str("Please enter a state: ", stateABB);
	checkState(table, point_STname, stateABB);
	table->rec[y].discount = get_code("Please enter discount code: ", code);
	table->rec[y].order_out = get_orders("Please enter outstanding orders: ", order);
	table->rec[y].balance_due = get_bal("Please enter balance due: ", bal);
	y++;
    table->rec[y+1].cust_id = 999;
}
/***********************
*Function to list file *
***********************/
void listFile(struct myRecords *table)
{
	int x;
	printf ("Cust ID\t Cust Name\t       State   Disc.     Bal Due      Order Out\n");
	for (x=0; x < 10; x++)
	{	
		if(table->rec[x].cust_id == 999)
		{
			x = 10;		
		}
		else
		{
			printf ("\n%i\t%-20s\t%-7s\t%c\t%0.2f\t\t%i", table->rec[x].cust_id, table->rec[x].cust_name, table->rec[x].states, table->rec[x].discount, table->rec[x].balance_due, table->rec[x].order_out);
		}
	}
}
/*************************
*Function to get strings *
*************************/
void get_str(char prompt[], char state[])
{
	printf("\n %s",prompt);
	gets(state);
}
/****************************
*Function to get characters *
****************************/
char get_char(char prompt[50])
{
	char c[50];
	printf("\n %s", prompt);
	gets(c);
	return c[0];
}

Open in new window

reesee324Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenDBACommented:
Hi reesee,

Look around line 305.  It looks like it's possible that y is never set in this loop.  If not, the code below that will use the uninitialized value of y as an index into the table.



Kent
0
reesee324Author Commented:
Ok I deleted where the y = x and just set it to x = 10 and now it runs through everything and asks all the questions but when you hit "N' to stop adding the records and list what you have I get another unhandled exception.
Unhandled exception at 0x010114a0 in Reynolds Assignment 4.exe: 0xC0000005: Access violation writing location 0x0000fb6b.
0
Kent OlsenDBACommented:
Do you get anything printed before you see the error?
0
10 Tips to Protect Your Business from Ransomware

Did you know that ransomware is the most widespread, destructive malware in the world today? It accounts for 39% of all security breaches, with ransomware gangsters projected to make $11.5B in profits from online extortion by 2019.

reesee324Author Commented:
Just the header but none of the info that I just typed in.
0
reesee324Author Commented:
I just realized also that once I enter the first record and it asks if you want to enter another if you type y then I get the same error.
Access violation writing location 0x0000f97b
0
Kent OlsenDBACommented:
Ok.  One of the things that doesn't happen is initialization.  Another thing that happens that is somewhat unusual is that you declare the table on the stack in the main function.  If the table gets quite large, this won't work well as the object could limit the stack or even overflow it.

Normally, variables (like this table) that last for the duration of the program would be declared in global memory.  Either that or what's declared in main() is a pointer to the table and the table is assigned storage with malloc() or calloc().

But I think that we can make this work as you have it.  The first thing that I'd do in main() is initialize the table.

int main()
{
      myRecords table, *point_table;
      point_table = &table;
      char cust;

        memset (point_table, 0, sizeof (table));

Then, check for a slot in the table being used/unused by testing the value of cust_id for zero/non-zero.  This shouldn't be much of an impact on your design.


Kent
0
reesee324Author Commented:
Okay sorry to sound dumb for asking this but when you say to check for the slot being used/unused would I just change my if statement in the for loop to if cust_id == 0? I've tried it and it doesn't work but I guess I've just been working on this too long. I've attached where I changed the code.
int main()
{
	myRecords table, *point_table;
	point_table = &table;

	char cust;
	memset (point_table, 0, sizeof (table));

	addRecord(point_table);
	cust = get_char ("Would you like to enter another return? ");
	cust = toupper(cust);

	while (cust == 'Y')
	{
		addRecord(point_table);
		cust = get_char ("Would you like to enter another return? ");
		cust = toupper(cust);
	}//end while
	
	listFile(point_table);
	return 0;

}//end of main
/**************************
*Function to add a record *
**************************/
void addRecord (struct myRecords *table)
{
	stateType STname, *point_STname;
	point_STname = &STname;

	char buf[50];
	char name[50];
	char stateABB[3];
	char code[50];
	char order[50];
	char bal[50];
	
	char string[50];
	int x;
	int y = 0;
	for (x=0; x < 10; x++)
	{	
		if (table->rec[x].cust_id == 0)
		{
			x = 10;		
		}
	}
	table->rec[y].cust_id = is_int("Please enter a customer id: ", buf);
	is_name("Please enter customer name: ", table->rec[y].cust_name);
	get_str("Please enter a state: ", stateABB);
	checkState(table, point_STname, stateABB);
	table->rec[y].discount = get_code("Please enter discount code: ", code);
	table->rec[y].order_out = get_orders("Please enter outstanding orders: ", order);
	table->rec[y].balance_due = get_bal("Please enter balance due: ", bal);
	y++;
}

Open in new window

0
Kent OlsenDBACommented:
That's pretty close.  Though you still need to set Y, since it's your index into the table.

      for (x=0; x < 10; x++)
      {      
            if (table->rec[x].cust_id == 0)
            {
                  y = x;
                  break;
            }
      }
      if (x == 10)
            printf ("Too many records for the table.\n");


0
reesee324Author Commented:
Okay thank you. I'm still getting that same error though and it keeps pointing to cust = get_char ("Would you like to enter another return? "); in main and it won't execute into the while loop or do anything after that.
0
Kent OlsenDBACommented:
Ok.  Can you post the code one more time?
0
reesee324Author Commented:

/**************************************************************************
*FILE: Reynolds Assignment 3.cpp										  *
*PROG: Theresa Reynolds													  *
*PURP: Allows users to enter data and print the output when they are done *
**************************************************************************/
#include <ctype.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stdio.h>

struct customers
{
	int cust_id;
	char cust_name[28];
	char states[3];
	char discount;
	double balance_due;
	int order_out;
};

struct myRecords
{
	customers rec[10];
};

struct state
{
	char name[15];
	char abbr[3];
};

struct stateType
{
	state lists[51];
};

using namespace std;

int is_int(char [], char []);
void is_name(char [], char []);
void get_str(char[], char[]);
int checkState(struct myRecords*, struct stateType*, char[]);
char get_code(char[], char[]);
int get_orders(char[], char[]);
float get_bal(char[], char[]);
char get_char(char[]);
void addRecord(struct myRecords*);
void listFile(struct myRecords*);

int main()
{
	myRecords table, *point_table;
	point_table = &table;

	char cust;
	memset (point_table, 0, sizeof (table));

	addRecord(point_table);
	cust = get_char ("Would you like to enter another return? ");
	cust = toupper(cust);

	while (cust == 'Y')
	{
		addRecord(point_table);
		cust = get_char ("Would you like to enter another return? ");
		cust = toupper(cust);
	}//end while
	
	listFile(point_table);
	return 0;

}//end of main

/*****************************
*Function to get customer id *
*****************************/
int is_int(char prompt[], char buf[])
{
	bool found = false;
	do{
		printf("\n %s",prompt);
		gets(buf);
		int i;
		int id;
		int y=0;
		for (i=0; buf[i]; i++)
		{
			if (!isdigit(buf[i]))
			{
				is_int("Please enter a customer id: ", buf);
			}	
			else
				
			{				
				id = atoi(buf);
				if(id < 998 && id > 0)
				{
					return id;
				}
				else
				{
					is_int("Please enter a customer id: ", buf);
				}
			}
		}
	} while (false);
}
/*******************************
*Function to get customer name *
*******************************/
void is_name(char prompt[], char name[])
{
	bool found = false;
	do{			
		printf("\n %s",prompt);
		gets(name);
		if (strlen(name) == 0)
		{
			is_name("Please enter customer name: ", name);
		}
	} while (false);
}
/******************************
*Binary search for  the state *
******************************/
int checkState (struct myRecords* table, struct stateType* STname, char stateABB[])
{
	static char f_time;
	f_time = 'Y';
	if (f_time == 'Y')
	{
		char buffer[50];
		FILE *fp;
		fp = fopen("STATES.DAT", "r");
		if (fp == NULL)
		{
			printf ("Error opening file! ");
		}
		 
		int counter = 0;
	
		while(!(feof(fp)))
		{
			
			fgets(STname->lists[counter].name, 20, fp);
			STname->lists[counter].name[strlen(STname->lists[counter].name)-1] = '\0';
			fgets(STname->lists[counter].abbr, 20, fp);
			STname->lists[counter].abbr[strlen(STname->lists[counter].abbr)-1] = '\0'; 
						
			++counter;
		}

		f_time == 'N';
	}
	
	
	int first=0,last = 50, middle, position=-1;
	bool found=false;
	
	while (!found && first <= last)
	{
		int Compare;
	    middle = (first + last) / 2;
		Compare = strcmp (STname->lists[middle].abbr, stateABB);
		if (Compare == 0)
		{
			found = true;
			position = middle;
		}
		else if (Compare > 0)
		{
			last = middle - 1;
		}
		else
		{      
			first = middle + 1;
		}
	}
	if (position == -1)
	{
		printf ("Not a valid state abbreviation");
		get_str("Please enter a state: ", stateABB);
	}
	else 
	{
		int y = 0;			
		stateABB = table->rec[y].states;
		y++;
	}
	
	return position;
}
/*******************************
*Function to get discount code *
*******************************/
char get_code(char prompt[], char code[])
{
	bool found = false;
	do{
		printf("\n %s", prompt);	
		gets(code);

		if (!strcmp(code, "A"))
		{
			return code[0];
		}
		else if (!strcmp(code, "B"))
		{
			return code[0];
		}
		else if (!strcmp(code, "C"))
		{
			return code[0];
		}
		else if (strlen(code) == 0)
		{
			return code[0];
		}
		else
		{
			get_code("Please enter discount code: ", code);
		}
	} while (false);
}
/************************************
*Function to get outstanding orders *
************************************/
int get_orders(char prompt[], char order[])
{
	bool found = false;
		printf("\n %s",prompt);
		gets(order);
		int i;
		int orders;
		int y=0;
		for (i=0; order[i]; i++)
		{
			if (!isdigit(order[i]))
			{
				get_orders("Please enter outstanding orders: ", order);
			}	
			else
			{				
				orders = atoi(order);
				if(orders > 0 && orders <= 30)				
				{
					return orders;
				}
				else
				{
					get_orders("Please enter outstanding orders: ", order);
				}
			}
			
		}
}
/*****************************
*Function to get balance due *
*****************************/
float get_bal(char prompt[], char bal[])
{
	bool found = false;
	do {
		printf("\n %s",prompt);
		gets(bal);
		int i;
		float balance;
		int y=0;
		for (i=0; i < strlen(bal); i++)
		{
			if (!isdigit(bal[i]))
			{
				get_bal("Please enter balance due: ", bal);
			}	
			else
			{
				balance = atof(bal);
				return balance;
			}
		}
	} while (false);
}
/**************************
*Function to add a record *
**************************/
void addRecord (struct myRecords *table)
{
	stateType STname, *point_STname;
	point_STname = &STname;

	char buf[50];
	char name[50];
	char stateABB[3];
	char code[50];
	char order[50];
	char bal[50];
	
	char string[50];
	int x;
	int y = 0;
	for (x=0; x < 10; x++)
	{	
		if (table->rec[x].cust_id == 0)
		{
			y = x;
			break;	
		}
	}
	table->rec[y].cust_id = is_int("Please enter a customer id: ", buf);
	is_name("Please enter customer name: ", table->rec[y].cust_name);
	get_str("Please enter a state: ", stateABB);
	checkState(table, point_STname, stateABB);
	table->rec[y].discount = get_code("Please enter discount code: ", code);
	table->rec[y].order_out = get_orders("Please enter outstanding orders: ", order);
	table->rec[y].balance_due = get_bal("Please enter balance due: ", bal);
	y++;
}
/***********************
*Function to list file *
***********************/
void listFile(struct myRecords *table)
{
	int x;
	printf ("Cust ID\t Cust Name\t       State   Disc.     Bal Due      Order Out\n");
	for (x=0; x < 10; x++)
	{	
		if(table->rec[x].cust_id == 0)
		{
			x = 10;		
		}
		else
		{
			printf ("\n%i\t%-20s\t%-7s\t%c\t%0.2f\t\t%i", table->rec[x].cust_id, table->rec[x].cust_name, table->rec[x].states, table->rec[x].discount, table->rec[x].balance_due, table->rec[x].order_out);
		}
	}
}
/*************************
*Function to get strings *
*************************/
void get_str(char prompt[], char state[])
{
	printf("\n %s",prompt);
	gets(state);
}
/****************************
*Function to get characters *
****************************/
char get_char(char prompt[50])
{
	char c[50];
	printf("\n %s", prompt);
	gets(c);
	return c[0];
}

Open in new window

0
Kent OlsenDBACommented:
Ok.  Let's start with some easy cleanup.

Line 78.  Function is_int ()
  Note the do/while condition.  while false?  That means you execute the block of code only once.
  It also means that the function could fall through the block of code an exit without returned a value.

Line 112.  Function is_name ()
  Same notes as for function is_int

Line 135.  You call fopen () on "STATES.DAT".  You never call fclose ();  (Insert about line 153.)

Line 192.  Function get_code ()
  Same notes as for function is_int

Line 229.  Function get_orders ()
  Same notes as for function is_int

Line 261.  Function get_bal ()
  Same notes as for function is_int


Let's get these cleaned up and see where we get.   :)

0
reesee324Author Commented:
Okay I've gotten all that cleaned up and I did have the fclose but I guess it just got deleted somewhere along the line (oops) of me rewriting everything. :) I'm still getting this: Access violation writing location 0x0000f5fb. New code now looks like this and the error is in the same place as before ***
#include <ctype.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stdio.h>

struct customers
{
	int cust_id;
	char cust_name[28];
	char states[3];
	char discount;
	double balance_due;
	int order_out;
};

struct myRecords
{
	customers rec[10];
};

struct state
{
	char name[15];
	char abbr[3];
};

struct stateType
{
	state lists[51];
};

using namespace std;

int is_int(char [], char []);
void is_name(char [], char []);
void get_str(char[], char[]);
int checkState(struct myRecords*, struct stateType*, char[]);
char get_code(char[], char[]);
int get_orders(char[], char[]);
float get_bal(char[], char[]);
char get_char(char[]);
void addRecord(struct myRecords*);
void listFile(struct myRecords*);

int main()
{
	myRecords table, *point_table;
	point_table = &table;

	char cust;
	memset (point_table, 0, sizeof (table));

	addRecord(point_table);
***	cust = get_char ("Would you like to enter another return? ");
	cust = toupper(cust);

	while (cust == 'Y')
	{
		addRecord(point_table);
		cust = get_char ("Would you like to enter another return? ");
		cust = toupper(cust);
	}//end while
	
	listFile(point_table);
	return 0;

}//end of main

/*****************************
*Function to get customer id *
*****************************/
int is_int(char prompt[], char buf[])
{
	printf("\n %s",prompt);
	gets(buf);
	int i;
	int id;
	int y=0;
	for (i=0; buf[i]; i++)
	{
		if (!isdigit(buf[i]))
		{
			is_int("Please enter a customer id: ", buf);
		}	
		else
			
		{				
		id = atoi(buf);
			if(id < 998 && id > 0)
			{
				return id;
			}
			else
			{
				is_int("Please enter a customer id: ", buf);
			}
		}
	}
}
/*******************************
*Function to get customer name *
*******************************/
void is_name(char prompt[], char name[])
{
	printf("\n %s",prompt);
	gets(name);
	if (strlen(name) == 0)
	{
		is_name("Please enter customer name: ", name);
	}
}
/******************************
*Binary search for  the state *
******************************/
int checkState (struct myRecords* table, struct stateType* STname, char stateABB[])
{
	static char f_time;
	f_time = 'Y';
	if (f_time == 'Y')
	{
		char buffer[50];
		FILE *fp;
		fp = fopen("STATES.DAT", "r");
		if (fp == NULL)
		{
			printf ("Error opening file! ");
		}
		 
		int counter = 0;
	
		while(!(feof(fp)))
		{
			
			fgets(STname->lists[counter].name, 20, fp);
			STname->lists[counter].name[strlen(STname->lists[counter].name)-1] = '\0';
			fgets(STname->lists[counter].abbr, 20, fp);
			STname->lists[counter].abbr[strlen(STname->lists[counter].abbr)-1] = '\0'; 
						
			++counter;
		}
		fclose(fp);
		f_time == 'N';
	}
	
	
	int first=0,last = 50, middle, position=-1;
	bool found=false;
	
	while (!found && first <= last)
	{
		int Compare;
	    middle = (first + last) / 2;
		Compare = strcmp (STname->lists[middle].abbr, stateABB);
		if (Compare == 0)
		{
			found = true;
			position = middle;
		}
		else if (Compare > 0)
		{
			last = middle - 1;
		}
		else
		{      
			first = middle + 1;
		}
	}
	if (position == -1)
	{
		printf ("Not a valid state abbreviation");
		get_str("Please enter a state: ", stateABB);
	}
	else 
	{
		int y = 0;			
		stateABB = table->rec[y].states;
		y++;
	}
	
	return position;
}
/*******************************
*Function to get discount code *
*******************************/
char get_code(char prompt[], char code[])
{
	printf("\n %s", prompt);	
	gets(code);
	if (!strcmp(code, "A"))
	{
	return code[0];
	}
	else if (!strcmp(code, "B"))
	{
		return code[0];
	}
	else if (!strcmp(code, "C"))
	{
		return code[0];
	}
	else if (strlen(code) == 0)
	{
		return code[0];
	}
	else
	{
		get_code("Please enter discount code: ", code);
	}
}
/************************************
*Function to get outstanding orders *
************************************/
int get_orders(char prompt[], char order[])
{
	printf("\n %s",prompt);
	gets(order);
	int i;
	int orders;
	int y=0;
	for (i=0; order[i]; i++)
	{
		if (!isdigit(order[i]))
		{
			get_orders("Please enter outstanding orders: ", order);
		}	
		else
		{				
			orders = atoi(order);
			if(orders > 0 && orders <= 30)				
			{
				return orders;
			}
			else
			{
				get_orders("Please enter outstanding orders: ", order);
			}
		}
		
	}
}
/*****************************
*Function to get balance due *
*****************************/
float get_bal(char prompt[], char bal[])
{
	printf("\n %s",prompt);
	gets(bal);
	int i;
	float balance;
	int y=0;
	for (i=0; i < strlen(bal); i++)
	{
		if (!isdigit(bal[i]))
		{
			get_bal("Please enter balance due: ", bal);
		}	
		else
		{
			balance = atof(bal);
			return balance;
		}
	}
}
/**************************
*Function to add a record *
**************************/
void addRecord (struct myRecords *table)
{
	stateType STname, *point_STname;
	point_STname = &STname;

	char buf[50];
	char name[50];
	char stateABB[3];
	char code[50];
	char order[50];
	char bal[50];
	
	char string[50];
	int x;
	int y = 0;
	for (x=0; x < 10; x++)
	{	
		if (table->rec[x].cust_id == 0)
		{
			y = x;
			break;	
		}
	}
	table->rec[y].cust_id = is_int("Please enter a customer id: ", buf);
	is_name("Please enter customer name: ", table->rec[y].cust_name);
	get_str("Please enter a state: ", stateABB);
	checkState(table, point_STname, stateABB);
	table->rec[y].discount = get_code("Please enter discount code: ", code);
	table->rec[y].order_out = get_orders("Please enter outstanding orders: ", order);
	table->rec[y].balance_due = get_bal("Please enter balance due: ", bal);
	y++;
}
/***********************
*Function to list file *
***********************/
void listFile(struct myRecords *table)
{
	int x;
	printf ("Cust ID\t Cust Name\t       State   Disc.     Bal Due      Order Out\n");
	for (x=0; x < 10; x++)
	{	
		if(table->rec[x].cust_id == 0)
		{
			x = 10;		
		}
		else
		{
			printf ("\n%i\t%-20s\t%-7s\t%c\t%0.2f\t\t%i", table->rec[x].cust_id, table->rec[x].cust_name, table->rec[x].states, table->rec[x].discount, table->rec[x].balance_due, table->rec[x].order_out);
		}
	}
}
/*************************
*Function to get strings *
*************************/
void get_str(char prompt[], char state[])
{
	printf("\n %s",prompt);
	gets(state);
}
/****************************
*Function to get characters *
****************************/
char get_char(char prompt[50])
{
	char c[50];
	printf("\n %s", prompt);
	gets(c);
	return c[0];
}

Open in new window

0
Kent OlsenDBACommented:
Ok.  :)

-- I see an issue at line 169.  It looks like the program returns a "random" value for position if the state code isn't found.

And you've flagged line 55 for some reason?

-- is_int can return the wrong value.

-- get_code can return the wrong value.

-- get_orders can return the wrong value.

-- get_bal can return the wrong value.


Are you getting warnings on these functions when you compile your program?

0
reesee324Author Commented:
On line 169 at the beginning I set the position to = -1 so then if the state isn't found the position is -1 which shows an error message to enter another state and I wasn't sure how to reset that other than to get str but I didn't know how you would set it to run the binary search again inside the function.

Line 55 I flagged because that is where I'm getting the error (Just so you could see exactly where I was talking about :))

Yes I get warnings for the functions but I was told to just ignore warnings.
0
Kent OlsenDBACommented:
The advice to ignore warnings isn't a good one.  :(  They're warnings for a reason.....

If you enter an invalid state code you ask again.  But accept the bad one the second time around.

toupper() is a pretty simple function.  You pass it a character and it returns one.  That suggests that the program has wandered into the ozone earlier in the execution and clobbered something related to the function.   I don't get the crash when I run it, but that doesn't mean that it's correct.

At line 219 you sequence your input.  Comment out lines 292 through 297 and test your program.  If it runs, take the comment off of line 292 and try again.  If that runs repeat for the next commented line, etc.


0
reesee324Author Commented:
It's the checkState(table, point_STname, stateABB);
Sometimes I wish I had a little more common sense to think of commenting out lines before :) I guess after working on things for so long you lose it haha. Anyways before I  put it into this function I had it just as checkState(point_STname, stateABB) and it worked fine going through the program.
I'm guessing that it's the table part being passed in that is throwing it off but I have to have the other structure passed into it in order to store the correct state into the states record of that structure unless there is another way to do it which I'm not quite sure on.
0
Kent OlsenDBACommented:
Well, let's simplify.  :)  That's usually a good thing...

The top half of the checkState function is just table loading.  Let's move that to it's own function, loadStates

Then in main(), call loadStates right after you call memset().  Cleaning up checkState is easier now, too.


Note that in checkStates you have this line:

        stateABB = table->rec[position].states;

That will only copy 1 character from the table.  And I think it's from the wrong table.  Do you want this:

        strcpy (stateABB,  STname->lists[position].abbr);


Kent



int loadStates ()
{
	char buffer[50];
	FILE *fp;
	fp = fopen("STATES.DAT", "r");
	if (fp == NULL)
	{
		printf ("Error opening file! ");
	}

	int counter = 0;

	while(!(feof(fp)))
	{
		fgets(STname->lists[counter].name, 20, fp);
		STname->lists[counter].name[strlen(STname->lists[counter].name)-1] = '\0';
		fgets(STname->lists[counter].abbr, 20, fp);
		STname->lists[counter].abbr[strlen(STname->lists[counter].abbr)-1] = '\0';

		++counter;
	}
	fclose(fp);
}

Open in new window

0
reesee324Author Commented:
The reason I have it going to the table->rec is because I need to store that state to the field under myRecords called states. I know with all the other functions you can just say table->rec[y].cust_id = get_id (...) and so on but since the search is an int and it returns a position I didn't know how else to store it to that myRecords structure any other way.
0
Kent OlsenDBACommented:

Take a closer look at line 177.  It takes the first chacter of table->rec[0].states and puts it into stateABB.  You want to copy two characters that are formatted as a string (the third character is the zero byte).

You're also copying from your table of records, not the table of state names/abbreviations.

          strcpy (stateABB,  STname->lists[position].abbr);

That line will copy the abbreviation from the states table to stateABB, which is what I think that you want to do.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
reesee324Author Commented:
Okay so this is what I changed it to and I'm still getting that same old error (starting to really hate that thing). This may sound stupid but you never know the answer til you ask right?? If you use the strcpy how will it know to go on to the next one in the counter and store for each one? I use y for everything else and I know the search is different but for each one it just adds y++ to it so how would it know to just go to the next one? Also do you think it could be because of the way I'm calling it in the addRecord function?? Just a thought and thanks for being so patient with me and my humor (which nothing is ever fun without :P)

get_str("Please enter a state: ", stateABB);
checkState(table, point_STname, stateABB); (I use point_table everywhere else but it won't work here, I had to use table, don't know if that would have anything to do with it though)
int checkState (struct myRecords* table, struct stateType* STname, char stateABB[])
{
int first=0,last = 50, middle, position=-1;
	bool found=false;
	
	while (!found && first <= last)
	{
		int Compare;
	    middle = (first + last) / 2;
		Compare = strcmp (STname->lists[middle].abbr, stateABB);
		if (Compare == 0)
		{
			found = true;
			position = middle;
		}
		else if (Compare > 0)
		{
			last = middle - 1;
		}
		else
		{      
			first = middle + 1;
		}
	}
	if (position == -1)
	{
		printf ("Not a valid state abbreviation");
		get_str("Please enter a state: ", stateABB);
	}
	else 
	{
		strcpy (stateABB,  STname->lists[position].abbr);
	}
	
	return position;
}

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.