Thread: struct data changes lost?

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    4

    struct data changes lost?

    I am running into a problem with this code. When I delete a item from the budget then exit the program the item is correctly removed from the array and the file is written without the deleted item in other words works as expected. it also works as expected if i display the budget and delete more etc.
    The oddity comes into play when i delete a budget item then go to add an item to the budget. the deleted items reappear. Thoughts? I have tried tracing this through the debugger in visual studio but i cant seam to find where it goes wrong...
    Any guidance is welcome.

    Code:
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    const int MAXIMUM_BUDGET_ITEMS = 500;
    const int MAXIMUM_USER_INPUT_CATEGORIES = 100;
    
    enum categoryType {income, expense};
    
    struct budget{
    	categoryType budgetCategory;
    	string categoryName;
    	double categoryAmount;
    	bool cleared;
    };
    void SetupBudget(budget budgetData[]);
    void QueryUserNewOldData(budget budgetData[]);
    bool LoadData(budget budgetData[]);
    void AddData(budget budgetData[]);
    int NumberOfItemsInArray(budget budgetData[]);
    bool StringHasSpace(string str);
    double GetCategoryAmount();
    bool GetCleared();
    bool GetCategoryType();
    char GetUserInput();
    string GetCategoryName();
    budget ClearBudgetItems();
    int GetMenuSelection(int lower, int upper);
    void DisplayBudget(budget budgetData[]);
    void SaveData(budget budgetData[]);
    void MainMenu(budget budgetData[]);
    void DeleteBudgetItem(budget budgetData[]);
    string userSelectItem(budget budgetData[]);
    bool isCategoryInArray(budget budgetData[], string categoryNameString);
    
    int main()
    {
    	budget budgetData[MAXIMUM_BUDGET_ITEMS];
    	SetupBudget(budgetData);
    	QueryUserNewOldData(budgetData);
    	MainMenu(budgetData);
    
    	return 0;
    }
    void SetupBudget(budget budgetData[])
    {
    	for (int i = 0; i < MAXIMUM_BUDGET_ITEMS; i++)
    	{
    		budgetData[i] = ClearBudgetItems();
    	}
    }
    void QueryUserNewOldData(budget budgetData[])
    {
    	char userChoice = '\0';
    	
    	userChoice = GetUserInput();
    
    	if (userChoice == 'E')
    	{
    		if (LoadData(budgetData) == false)
    		{
    			AddData(budgetData);
    		}
    	}
    	if (userChoice == 'N')
    	{
    		AddData(budgetData);
    	}	
    }
    bool LoadData(budget budgetData[])
    {
    	bool success = false;
    	char categoryType;
    	char cleared;
    	ifstream inFile;
    	inFile.open("BUDGET.TXT");
    	int i = 0;
    		while (inFile.is_open() && !inFile.eof())
    		{
    			inFile >> categoryType >> budgetData[i].categoryName >> budgetData[i].categoryAmount >> cleared;
    
    			if (categoryType == 'I')
    			{
    				budgetData[i].budgetCategory = income;
    			}
    			if (categoryType == 'E')
    			{
    				budgetData[i].budgetCategory = expense;
    			}
    			if (cleared == 'Y')
    			{
    				budgetData[i].cleared = true;
    			}
    			if (cleared == 'N')
    			{
    				budgetData[i].cleared = false;
    			}
    
    			success = true;
    			i++;
    		}
    		if (!inFile || inFile.eof() || success == false)
    		{
    			cout << endl << "Could not open file to load data." << endl
    				<< "Please enter some data!" << endl;
    		}
    	inFile.close();
    	return success;
    }
    void AddData(budget budgetData[])
    {
    	char keepEntering = '\0';
    	int limit = 0;
    	limit = NumberOfItemsInArray(budgetData);
    	for 
    		(int i = 0; 
    		(limit + i) < (limit + MAXIMUM_USER_INPUT_CATEGORIES) 
    		&& (limit + i) < MAXIMUM_BUDGET_ITEMS;
    		i++)
    	{
    		if (GetCategoryType() == true)
    		{
    			budgetData[i+limit].budgetCategory = income;
    		}
    		else
    		{
    			budgetData[i+limit].budgetCategory = expense;
    		}
    		budgetData[i+limit].categoryName = GetCategoryName();
    		budgetData[i+limit].categoryAmount = GetCategoryAmount();
    		budgetData[i+limit].cleared = GetCleared();
    		do{
    			cout << endl << "Enter another item Y/N?";
    			cin >> keepEntering;
    			if (toupper(keepEntering) == 'N')
    				i = MAXIMUM_USER_INPUT_CATEGORIES;
    		} while (toupper(keepEntering) != 'N' && toupper(keepEntering) != 'Y');
    	}
    }
    int NumberOfItemsInArray(budget budgetData[])
    {
    	int items = 0;
    	bool quit = false;
    	for (int i = 0; quit == false; i++)
    	{
    		if (budgetData[i].categoryName != "\0")
    			items++;
    		else
    			quit = true;
    	}
    	return items;
    }
    bool GetCategoryType()
    {
    	char userChoice = '\0';
    	do {
    	cout << "Is this an (I)ncome or (E)xpense?" << endl << "Choice : ";
    	cin >> userChoice;
    	userChoice = toupper(userChoice);
    	if (userChoice != 'I' && userChoice != 'E')
    	{
    		cout << endl << "!!!!!Please enter I or E" << endl << endl;
    	}
    	} while (userChoice != 'I' && userChoice != 'E');
    
    	if (userChoice == 'I')
    	{
    		return true;
    	}
    	if (userChoice == 'E')
    	{
    		return false;
    	}
    	return false; //saftey first
    }
    bool GetCleared()
    {
    	char userChoice = '\0';
    	do {
    	cout << "Has this item cleared enter Y/N" << endl << "Choice : ";
    	cin >> userChoice;
    	userChoice = toupper(userChoice);
    	if (userChoice != 'Y' && userChoice != 'N')
    	{
    		cout << endl << "!!!!!Please enter Y or N" << endl << endl;
    	}
    	} while (userChoice != 'Y' && userChoice != 'N');
    
    	if (userChoice == 'Y')
    	{
    	return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    double GetCategoryAmount()
    {
    	double amount = 0;
    	do {
    		cout << "Enter the ammount for the item" << endl
    				<< "The item must be positive, i.e. 433.22" << endl
    				<< "Please enter the ammount: ";
    		cin >> amount;
    	} while (amount < 0);
    	
    	return amount;
    }
    string GetCategoryName()
    {
    	string name = "\0";
    	do {
    		cout << "Enter the name for the category" << endl
    				<< "The category name must be 15 charcters or less" << endl
    				<< "and it may not contain any spaces" << endl;
    		cin >> name;
    	} while (name.size() >= 15 || StringHasSpace(name));
    	return name;
    }
    bool StringHasSpace(string str)
    {
    	for (unsigned int i = 0; i < str.length(); i++)
    	{
    		if (str[i] == ' ')
    		return true;
    	}
    	return false;
    }
    char GetUserInput()
    {
    	char userChoice = '\0';
    	do {
    		cout << "Which Data would you like to use?" << endl << "		N - New budget data" << endl;
    		cout << "		E - Existing budget data" << endl << "Choice : ";
    		cin >> userChoice;
    		userChoice = toupper(userChoice);
    		if (userChoice != 'E' && userChoice != 'N')
    		{
    			cout << endl << "!!!!!Please enter E or N" << endl << endl;
    		}
    		} while (userChoice != 'E' && userChoice != 'N');
    	return userChoice;
    }
    budget ClearBudgetItems()
    {
    	budget b;
    	b.categoryAmount = 0.00;
    	b.categoryName = "\0";
    	b.cleared = false;
    	b.budgetCategory = income;
    	
    	return b;
    }
    int GetMenuSelection(int lower, int upper)
    {
    	int menuSelection = 0;
    	do{
    		cin >> menuSelection;
    		if (menuSelection < lower || menuSelection > upper)
    		{
    			cout << "Your selection must be between " << lower << " and " 
    					<< upper << endl << "Please try again: ";
    		}
    	} while (menuSelection < lower || menuSelection > upper);
    	return menuSelection;
    }
    void DisplayBudget(budget budgetData[])
    {
    	int numberOfBudgetItems = 0;
    	numberOfBudgetItems = NumberOfItemsInArray(budgetData);
    
    	cout << endl << "INCOME:" << endl;
    	cout << "Item Amount Cleared" << endl;
    		for (int i = 0; i < numberOfBudgetItems; i++)
    		{
    			if (budgetData[i].budgetCategory == income)
    			{
    				cout << endl << budgetData[i].categoryName << " " << budgetData[i].categoryAmount;
    				if (budgetData[i].cleared == true)
    					cout << " *";
    			}
    		}	
    	cout << endl << endl << "Expense:" << endl;
    	cout << "Item Amount Cleared" << endl;
    		for (int i = 0; i < numberOfBudgetItems; i++)
    		{
    			if (budgetData[i].budgetCategory == expense)
    			{
    				cout << endl << budgetData[i].categoryName << " " << budgetData[i].categoryAmount;
    				if (budgetData[i].cleared == true)
    					cout << " *";
    			}
    		}
    }
    void SaveData(budget budgetData[])
    {
    	char save = '\0';
    
    	do{
    		cout << "Would you like to save data Y/N?";
    		cin >> save;
    	} while ((toupper(save) != 'Y') && (toupper(save) !='N'));
    
    	if (toupper(save) == 'Y')
    	{
    		ofstream outFile;
    		outFile.open("BUDGET.TXT");
    		for (int i = 0; i < NumberOfItemsInArray(budgetData); i++)
    		{ 
    			if (budgetData[i].budgetCategory == income)
    			{
    				outFile << "I ";
    			}
    			if (budgetData[i].budgetCategory == expense)
    			{
    				outFile << "E ";
    			}
    
    			outFile << budgetData[i].categoryName << " " << budgetData[i].categoryAmount << " ";
    			
    			if (budgetData[i].cleared == true)
    			{
    				outFile << 'Y' << endl;
    			}
    			else
    			{
    				outFile << 'N' << endl;
    			}
    		}
    		outFile.close();
    	}
    }
    void MainMenu(budget budgetData[])
    {
    	bool quit = false;
    	do{
    		cout << endl << endl 
    			<< "Main Menu!" << endl
    			<< "(1)Display Budget" << endl
    			<< "(2)Add Budget Item" << endl
    			<< "(3)Find Budget Category" << endl
    			<< "(4)Delete Budget Item" << endl
    			<< "(5)Exit" << endl
    			<< "Enter Your Selection: ";
    	switch(GetMenuSelection(1, 5))
    	{
    		case 1: DisplayBudget(budgetData);
    			break;
    		case 2: AddData(budgetData);
    			break;
    		case 3: //FindData(budgetData);
    			break;
    		case 4:
    			DeleteBudgetItem(budgetData);
    			break;
    		case 5:
    			quit = true;
    			SaveData(budgetData);
    			break;
    	}
    	}while (quit == false);
    }
    void DeleteBudgetItem(budget budgetData[])
    {
    	char itemSentry = 'n';
    
    	do{
    		string itemToDelete = userSelectItem(budgetData);
    		int numberOfItemsInBudget = NumberOfItemsInArray(budgetData);
    
    		for (int i = 0; i < numberOfItemsInBudget; i++)
    		{
    
    			if (budgetData[i].categoryName == itemToDelete)
    			{
    				for (int x = i; x < numberOfItemsInBudget; x++)
    				{	
    					categoryType budgetCategoryTemp;
    					string categoryNameTemp;
    					double categoryAmountTemp;
    					bool clearedTemp;
    
    					budgetCategoryTemp = budgetData[x].budgetCategory;
    					categoryNameTemp = budgetData[x].categoryName;
    					categoryAmountTemp = budgetData[x].categoryAmount;
    					clearedTemp = budgetData[x].cleared;
    
    					budgetData[x].budgetCategory = budgetData[x+1].budgetCategory;
    					budgetData[x].categoryName = budgetData[x+1].categoryName;
    					budgetData[x].categoryAmount = budgetData[x+1].categoryAmount;
    					budgetData[x].cleared = budgetData[x+1].cleared;
    
    					budgetData[x+1].budgetCategory = budgetCategoryTemp;
    					budgetData[x+1].categoryName = categoryNameTemp;
    					budgetData[x+1].categoryAmount = categoryAmountTemp;
    					budgetData[x+1].cleared = clearedTemp;
    					
    					if (x == numberOfItemsInBudget - 1)
    					{
    						budgetData[x] = ClearBudgetItems();
    					}
    				}
    			}
    		}
    		
    		cout << endl << endl << "Would you like to delete another category (Y)es or (N)o?";
    		cin >> itemSentry;
    		itemSentry = toupper(itemSentry);
    	} while(itemSentry != 'N');
    }
    string userSelectItem(budget budgetData[])
    {
    	string userInput = "\0";
    	do{
    		DisplayBudget(budgetData);
    	
    		cout << endl << endl << "Enter the name of the item you would like to delete: ";
    		cin >> userInput;
    
    		if(isCategoryInArray(budgetData, userInput))
    		{
    			return userInput;
    		}
    		else
    		{
    			cout << endl << "**Please type the category exactly as shown**" << endl;
    		}
    
    	}while(!isCategoryInArray(budgetData, userInput));
    
    	return userInput;
    }
    bool isCategoryInArray(budget budgetData[], string categoryNameString)
    {
    	int itemsInArray = NumberOfItemsInArray(budgetData);
    
    	for (int i = 0; i < itemsInArray; i++) 
    	{
    		if (budgetData[i].categoryName == categoryNameString)
    		{
    			return true;
    		}
    	}
    
    	return false;
    }

  2. #2
    Registered User
    Join Date
    Apr 2010
    Posts
    4
    n/m found the issue.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Your delete function appears to swap one too far, so you end up with something like
    Code:
    [0] some item
    [1] some item
    [2] some item
    [3] blank spot
    [4] deleted item
    Then when you add something, you put that something in spot [3], and now [4] is "seen" (since all your loops break at a blank spot, they didn't "see" the item in spot [4]).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Link List math
    By t014y in forum C Programming
    Replies: 17
    Last Post: 02-20-2009, 06:55 PM
  2. Replies: 8
    Last Post: 03-10-2008, 11:57 AM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. Bi-Directional Linked Lists
    By Thantos in forum C Programming
    Replies: 6
    Last Post: 12-11-2003, 10:24 AM
  5. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM