Here, better yet, I will give you a screenshot!
User Media - TinyPic - Free Image Hosting, Photo Sharing & Video Hosting
Here, better yet, I will give you a screenshot!
User Media - TinyPic - Free Image Hosting, Photo Sharing & Video Hosting
Oh, well, the reason I thought data[] could be used is because I am calling it through using the Employee class like I do in the sorting function.
If only I could use the buttons, heh-heh.
Anyway, read post #15.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
See, this is why I am confused:
Using data[] here worked, but in the searching it doesn't...? Any idea?Code:// Sort fuction used to sort through the employee struct and sort by last name else, customer ID void Employees::sortNameeID() { int smallestOrLargest; int index; for ( int i = 0; i < size-1; i++ ) { int smallestOrLargest = i; for ( int index = i + 1; index < size; index++ ) { int cmpName = strcmp(data[index].eLName, data[smallestOrLargest].eLName); if (cmpName<0) { smallestOrLargest = index; } else if (cmpName==0) { // names match if (data[index].eID<data[smallestOrLargest].eID) { smallestOrLargest = index; } } } if (smallestOrLargest != i) { //swap them Employee temp = data[i]; data[i] = data[smallestOrLargest]; data[smallestOrLargest] = temp; } } }
This is annoying...
Alright, so I changed the function a bit to match the others...here is the declaration inside the public under the employees class:
void inSearch();
Here is the error:
http://i43.tinypic.com/11goo6e.jpg
Because data[] is a member of class Employees.
I know this sounds like a drag, but (this is kind of what I meant before) you are not saving yourself any time or trouble by writing so much code involving (clearly) numbers of concepts (such as classes) which you have between zero and no experience with. In the end, it will only take you longer to debug, and the concepts will still have some fuzzy edges in your mind.
You should write a couple short, simple programs that focus not on the goals of your assignment but on specific C++ concepts that you are using within it it. This will give you a place to quickly and simple test "a premise" with regard to how to use the syntax. So here's an example:
Of course, this works and contains no errors, but if I had used:Code:#include <iostream> using namespace std; class test { public: int data; test (int x) { data = x; } }; int main () { test eg(666); cout << eg.data <<endl; return 0; }
instead, there would be a problem. If I couldn't find a solution myself, I could easily post that code and ask "why is data undefined?" and you would have your answer in probably a few minutes, from just about anyone. Rather than expecting someone to go thru all those details -- which can happen, but, well, I have to make dinner...etc...and it's taken you most of an hour to get this far.Code:cout << data <<endl;
Notice above, many irrelevant details and such eliminated. I promise, this will make it easier for you too
Last edited by MK27; 05-14-2010 at 07:33 PM.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
Alright, I got this to work without errors, now I just need to figure out how to get this thing to compare and search the array the right way...
Call Function:Code:// Search Array void Employees::searchNameeID() { int index; string target; cout << "Please enter last name to search for: "; cin >> target; cin.ignore(); for ( int i = 0; i < size-1; i++ ) { for(int index = i + 1; index < size; index++){ if(data[index].eLName == target){ cout << data[index].eLName << ", " << data[index].eName << "\n"; // Last Name, First Name cout << data[index].eStreetNum << " " << data[index].eStreetName << "\n"; // Street Number Street Name cout << data[index].eCity << ", " << data[index].eState << " " << data[index].eZip << "\n"; // City, State Zip } } } }
So, now that I did this, how exactly would I go about searching for the data[index].eLName and comparing it to the target string?Code:// Search for employee xEmployee.searchNameeID();
Why can't you just use the STL? As long as you have strings going, a vector of employees could get rid of the array, buy you out of the box sorting and with a simple helper function, searching as well...
Alright, so everyone will be happy to know that I finished it!!!! Everything works now!!!
Thank you everyone for putting up with me being stupid. :P Thanks a ton for making me think through it!!
Just because you helped me!:
Code:/****************************************************** ** Name: Joshua Long ** Filename: CPP_FINAL1.cpp ** Project Description: Enter the number of employees you want to input into the database, enter all of the employees and then sort the employees by last name. Prompt user to search for an employee by last name then display employee. ** Output: Employee data that was entered and then organized by the program to have better formatting. ** Input: Employee data ** Strees Level: Very HIGH ;) ******************************************************/ // Include Files #include <iostream> // used for cin, cout #include <iomanip> #include <string.h> #include <stdio.h> using namespace std; const int MAX_NAME_SIZE = 22; // Max size for names const int MAX_SIZE = 25; // Max size for all other strings // Employee Structure (Used for all employees struct Employee { // Chars used instead of strings for use of spaces char eName[MAX_NAME_SIZE], eLName[MAX_NAME_SIZE], eStreetName[MAX_SIZE], eCity[MAX_SIZE], eState[MAX_SIZE]; int eID, eStreetNum, eZip; void inNameeID(); }; // Max amount of employees allowed in program const int MAX_EmployeeS = 50; // The Employees class class Employees { public: // Fuction Prototypes void inEmployees(); void inNameeID(); void sortNameeID(); void searchNameeID(); void print(const char *prompt); // Private declarations private: Employee data[MAX_EmployeeS]; int size; }; // Main Processing int main() { //xEmployee.print("Original list"); // Used to print original //xEmployee.print("Alphabetized list"); // Used to print aplha list // Create new instance of Employees (stores all employee's data) Employees xEmployee; // Display which employee is being input xEmployee.inEmployees(); // Prompt for input of the employee data and display entered results xEmployee.inNameeID(); xEmployee.print("Initial Employee Data"); // Sort the employee data by last name xEmployee.sortNameeID(); // Print the employees that have been entered xEmployee.print("Sorted Employee List"); cout << endl << endl; // Skip a few lines after list displayed // Search for employee xEmployee.searchNameeID(); cout << endl; //Pause program before shutting down system("PAUSE"); } // Search Array void Employees::searchNameeID() { int index; string target; cout << "Please enter last name to search for: "; cin >> target; cin.ignore(); cout << endl; for(int index = 1; index < size; index++){ if(data[index].eLName == target){ cout << data[index].eLName << ", " << data[index].eName << "\n"; // Last Name, First Name cout << data[index].eStreetNum << " " << data[index].eStreetName << "\n"; // Street Number Street Name cout << data[index].eCity << ", " << data[index].eState << " " << data[index].eZip << "\n"; // City, State Zip } } } // Prompt for the user input on the employee's data void Employee::inNameeID() { cout << "First Name: "; cin.getline( eName, MAX_NAME_SIZE); // First Name cout << "Last Name: "; cin.getline( eLName, MAX_NAME_SIZE); // Last Name cout << "Street Number: "; cin >> eStreetNum; cin.ignore(); // Street Number cout << "Street Name: "; cin.getline( eStreetName, MAX_SIZE); // Street Name cout << "City: "; cin.getline( eCity, MAX_SIZE); // City cout << "State: "; cin.getline( eState, MAX_SIZE); // State cout << "Zip Code: "; cin >> eZip; cin.ignore(); // Zip Code cout << "Customer ID: "; cin >> eID; cin.ignore(); // Customer ID cout << endl; } // Prompt for how many employees should be entered void Employees::inEmployees() { cout << "Enter number of Employees (1 . . " << MAX_EmployeeS << ")" << endl << '>'; cin >> size; cin.ignore(); } // Display which employee is being entered void Employees::inNameeID() { for ( int count = 0; count < size; count++ ) { cout << "Employee " << (count + 1) << endl; data[count].inNameeID(); } } // Print the employees that have been entered void Employees::print(const char *prompt) { cout << prompt << endl; cout << "------------------------------" << endl; for ( int count = 0; count <size; count++ ) { cout << data[count].eLName << ", " << data[count].eName << "\n"; // Last Name, First Name cout << data[count].eStreetNum << " " << data[count].eStreetName << "\n"; // Street Number Street Name cout << data[count].eCity << ", " << data[count].eState << " " << data[count].eZip << "\n"; // City, State Zip //cout << setw( 8 ) << left << "Customer ID: " <<data[count].eID << "\n"; // Customer ID cout << endl; } cout << endl; } // Sort fuction used to sort through the employee struct and sort by last name else, customer ID void Employees::sortNameeID() { int smallestOrLargest; int index; for ( int i = 0; i < size-1; i++ ) { int smallestOrLargest = i; for ( int index = i + 1; index < size; index++ ) { int cmpName = strcmp(data[index].eLName, data[smallestOrLargest].eLName); if (cmpName<0) { smallestOrLargest = index; } else if (cmpName==0) { // names match if (data[index].eID<data[smallestOrLargest].eID) { smallestOrLargest = index; } } } if (smallestOrLargest != i) { //swap them Employee temp = data[i]; data[i] = data[smallestOrLargest]; data[smallestOrLargest] = temp; } } }
I am pleased to hear you made it; many do not and when they don't get an immediate answer they give up. After reading your thread earlier I thought it would be fun to sit down and see what kind of solution I could come up with in the shortest amount of time using nothing but the C++ standard. Additional points were for creating an employee mgmt class that could sort and search without me having to implement any of that code. To the rescue came the std::map class. I typed the map to use strings as the key field and an instance of Employee as the value. With that in place I wrote a couple of simplistic printing searching methods and (what took the most time) a reasonable test function to it all to show it all works and to generate data for the test. I have a tarball of it here:
http://jbcobb.net/bin/sortsearchdemo.tar.gz. You can just look at the source or if you need to compile it to see it run, install cmake if you don't already have it (I forgot your platform but it is available for all major platforms (Linux, Windows, Mac, etc). To build it, just run "cmake ." from the same folder as the CMakeLists.txt file and then type make. Note that this was not to do your program requirements but rather to demo how the STL can be used for a lot of things. This project will create a shared object library (or DLL on Winders) and a main executable that just calls the testEmployeeClass() method in the library. stl_sort_search.hpp/.cpp implements the testing function as well as a CEmployeeManager class which does the heavy lifting (such as there is here).
Started with a very simple Employee class with copy constructor (needed for many STL functions).
Code://****************************************************************** //* File:employee.hpp //* //* Description:simple employee class //* //* Date:2010-05-14 //* //* Author:jeff cobb //****************************************************************** //* R E V S I O N S //* //****************************************************************** #ifndef EMPLOYEE_HPP #define EMPLOYEE_HPP #include <string> using namespace std; class Employee { private: string strLastName; string strFirstName; string strAddress; string strCity; string strState; string strZip; public: Employee(): strLastName(""), strFirstName(""), strAddress(""), strCity(""), strState(""), strZip(""){}; Employee(const Employee &ref) { strLastName = ref.strLastName; strFirstName = ref.strFirstName; strAddress = ref.strAddress; strCity = ref.strCity; strState = ref.strState; strZip = ref.strZip; } Employee(string &strLN, string &strFN, string &strAdr, string &strCt, string &strSt, string strZ) { strLastName = strLN; strFirstName = strFN; strAddress = strAdr; strCity = strCt; strState = strSt; strZip = strZ; } void setLastName(string &str) { strLastName = str; } string getLastName() { return strLastName; } void setFirstName(string &str) { strFirstName = str; } string getFirstName() { return strFirstName; } void setAddress(string &str) { strAddress = str; } string getAddress() { return strAddress; } void setCity(string &str) { strCity = str; } string getCity() { return strCity; } void setState(string &str) { strState = str; } string getState() { return strState; } void setZip(string &str) { strZip = str; } string getZip() { return strZip; } }; #endif
Here is the header for the manager class:
and finally the implementation:Code:/************************************************* * File: stl_sort_search.hpp *************************************************/ #ifndef __STL_SORT_SEARCH_HPP #define __STL_SORT_SEARCH_HPP #include <map> #include <iostream> #include <string> using namespace std; #include "employee.hpp" class CEmployeeManager { private: // this will hold all of the employees. // because it is a map (tree) it will automatically // sort them on insertion so that need is taken care // of. The key for the map is a string of the last // name. Alter this if you need to search by something else map<string, Employee> Employees; public: // ctor. doesn't have much to do CEmployeeManager(){}; // add an employee to our data store. // return true if add is successful, false // if employee is already here bool addEmployee(Employee newEmp); // print out a list of employees sorted by last name void printSortedList(); // look up an employee. Return false if not // found, true if found and set into Emp bool lookupEmployee(string strLastName, Employee &Emp); // pretty print an employee void printEmployee(Employee &Emp); }; int testEmployeeClass(int nNumberOfEmployees); #endif
Nothing in main so I didn't add it here. Follow the link above if you want the whole project.Code:/************************************************* * File: stl_sort_search.cpp *************************************************/ #include "stl_sort_search.hpp" #include <string.h> #include <stdio.h> #define MAX_NAMES 25 // test names... const char *nameList[] = { "Jones", "Brown", "White", "Johnson", "Stratten", "Townsend", "Fielding", "Anderson", "Middleton", "Kirby", "Lee", "Burnap", "Golden", "Nash", "Yang", "Ullman", "Vogelman", "Charleston", "Deitel", "Stroustrup", "Kernigan", "Richie", "Cook", "Dempsey" }; int testEmployeeClass(int nNumberOfEmployees) { int nResultCode = 0; if( nNumberOfEmployees >= MAX_NAMES) { cout << "Too many names in test (" << nNumberOfEmployees << ")" << endl; nResultCode = -1; return nResultCode; } CEmployeeManager EmpMgr; // generate some employees int nCount; for(nCount = 0; nCount < nNumberOfEmployees; nCount++) { Employee Emp; string strLastName = string(nameList[nCount]); Emp.setLastName(strLastName); char buf[30]; memset(buf, 0, 30); sprintf(buf, "FirstName%d", nCount); string strFN = string(buf); Emp.setFirstName(strFN); memset(buf, 0, 30); sprintf(buf, "%d00 Address Lane", nCount); string strAddress = string(buf); Emp.setAddress(strAddress); memset(buf, 0, 30); sprintf(buf, "City%d", nCount); string strCity(buf); Emp.setCity(strCity); memset(buf, 0, 30); sprintf(buf, "State%d", nCount); string strState(buf); Emp.setState(strState); memset(buf, 0, 30); sprintf(buf, "%d0987", nCount); string strZip(buf); Emp.setZip(strZip); // insert into map if( EmpMgr.addEmployee(Emp)) { cout << "Added employee #" << nCount << " successfully" << endl; } else { cout << "Epic fail adding employee " << nCount << ". Aborting test." << endl; nResultCode = -1; return nResultCode; } } // now lets search for an employee cout << "Search test..." << endl; string strSearchKey = nameList[2]; Employee resultEmp; if( EmpMgr.lookupEmployee(strSearchKey, resultEmp)) { cout << "Searched for " << strSearchKey << " and found:" << endl; EmpMgr.printEmployee(resultEmp); } else { cout << "Failed to find " << strSearchKey << ". Aborting." << endl; nResultCode = -1; return nResultCode; } // print out sorted list cout << "Sorting and printing test.." << endl; cout << endl << "List of employees: " << endl; EmpMgr.printSortedList(); return nResultCode; } // pretty print an employee void CEmployeeManager::printEmployee(Employee &Emp) { cout << "******************************" << endl << "Last Name: " << Emp.getLastName() << endl << "First Naem: " << Emp.getFirstName() << endl << "Address: " << Emp.getAddress() << endl << "City: " << Emp.getCity() << endl << "State: " << Emp.getState() << endl << "Zip: " << Emp.getZip() << endl << "******************************" << endl; } // add an employee to our data store. // return true if add is successful, false // if employee is already here bool CEmployeeManager::addEmployee(Employee newEmp) { bool bSuccess = false; map<string, Employee>::iterator itr = Employees.find(newEmp.getLastName()); if(itr != Employees.end()) { // last name already exists, set result and return bSuccess = false; } else { // this is a new employee Employees[newEmp.getLastName()] = newEmp; bSuccess = true; } return bSuccess; } // print out a list of employees sorted by last name void CEmployeeManager::printSortedList() { // Since the employees are already sorted by last name // we just walk the map in natural order and print them out map<string, Employee>::iterator ptr = Employees.begin(); while(ptr != Employees.end()) { printEmployee((*ptr).second); ptr++; } cout << "End of list." << endl; } // look up an employee. Return false if not // found, true if found and set into Emp bool CEmployeeManager::lookupEmployee(string strLastName, Employee &Emp) { bool bSuccess = false; map<string, Employee>::iterator ptr = Employees.find(strLastName); if(ptr != Employees.end()) { // if ptr is not pointing to the end of the list // the node it IS pointing at is a winner Emp = (*ptr).second; bSuccess = true; } return bSuccess; }
I have a few suggestions about some of what I would change with that:
The copy-constructor can be removed:
Really you should never implement the copy-constructor manually whenever the default generated version will already do the right thing. In this case it will do the right thing because strings already know how to copy-construct themselves. What's more, the auto-generated one is more efficient that what you wrote because you used assignment rather than construction, and that incolved the extra step of destroying the old value first, even if the old value also happened to be an empty string.
Also with this:The default constructor for strings make them empty, thus all you would need is:Code:Employee(): strLastName(""), strFirstName(""), strAddress(""), strCity(""), strState(""), strZip(""){};The getters should be marked const. Lots of getters and setters indicates poor encapsulation anyway, but I wont go into that.Code:Employee() {}
None of the strings should be passed merely by reference. Ideally they would all be passed by const reference.
Prefer ptr->second over (*ptr).second
Remove the memsets. In C++ the ideal thing to use is std::fill, but here there is no need anyway. You could use the following for zero initialisation if you wish:However even better that that, stringstreams are your friendCode:char buf[30] = {};
Another recommendation:The second const stops you doing nameList[i] = "Some Other String";Code:static const char * const nameList[] =
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
Well I appreciate all of the tips though I really didn't need them as I was keeping my primary goal in mind to demonstrate how the OP could solve both this (searching) and his other problem (sorting) by leveraging the STL. The rest is just window-dressing. I am surprised that I did not get the namespace nazis on me for 'polluting the namespace' by using namespace std.
Re: Copy ctor: true enough in this case but in general having a copy ctor is a good thing.
Re: Initialization ctor: again, true enough in this case but being in a habit of initializing your variables is s a good thing.
Re: memset vs std::fill: agreed although either will work just as well.
Re: const and the nameList: At this point I was just trying to get through the test code as quickly as possible.
Re: ptr-> vs (*ptr). : you say tomato, I say tomahto. One is not inherently more correct than the other.
Re: us of string streams: That did occur to me, it really did. The reason I did not use it over the more old-school sprintf() stuff is that I was trying to keep the OP in mind. Basically if he/she didn't know that std::map could be used in this manner, I didn't want to confuse him by adding more std:: stuff, hopefully so he could focus on the solution that I presented here. In other cases, stringstreams are indeed my friend
Re: getters and setters: This is the first time I have ever heard that they are bad for encapsulation when indeed that is what they facilitate. Care to back that statement up?
Re: getters and using const: agreed and in production code I do. Again for me this was an exercise to see how quickly I could generate a solution for his/her problem (while eating dinner and watching Fringe with the wife).
Alright, we have a new problem here...this works and everything that it needs to right now, but for some odd reason, the program keeps being unresponsive...could someone show me the way? :P I don't know why it is doing that.
Code:#include <cstdlib> #include <iostream> using namespace std; class BaseAcc { public: // Contstructors BaseAcc(string aNamein, int aNumberin, double aBalancein){ aName = aNamein; aNumber = aNumberin; aBalance = aBalancein; } BaseAcc(){ aName = ""; aNumber = 0; aBalance = 0; } // Mutator functions void setAccName(string aNamein) { aName = aNamein; } void setAccNumber(int aNumberin) { aNumber = aNumberin; } void setBalance(double aBalancein) { aBalance = aBalancein; } // Accessor functions string getName() { return aName; } int getAccNum() { return aNumber; } double getBalance() { return aBalance; } // Member functions string Account() { cout << "-----Account-----" << endl; cout << aName << endl; cout << "Account Number: " << aNumber << endl; cout << "Balance: " << "$" << aBalance << endl; cout << "-----Account-----" << endl; } private: // Member data string aName; int aNumber; double aBalance; };// End of BaseAcc class Savings : public BaseAcc { private: double APR; double DepositAmount, WithdrawAmount; public: Savings(double DepositAmountin, double WithdrawAmountin, double APRin){ DepositAmount = DepositAmountin; WithdrawAmount = WithdrawAmountin; APR = APRin; } Savings(){ DepositAmount = 0; WithdrawAmount = 0; APR = 0.04; } void Deposit() { cout << "Amount to deposit: "; } }; int main(int argc, char *argv[]) { BaseAcc bob; bob.setAccName("Bob"); bob.setAccNumber(559598); bob.setBalance(44000); cout << bob.Account() << endl; system("PAUSE"); return EXIT_SUCCESS; }
Where does yours stop reacting to input? system("PAUSE") does nothing for non-Windows platforms which put this outside of the amount of work I want to put into the solution but knowing which line it stops on could be all the clues we need to solve this.