c++ searching from a text file ,when I terminate and run the program again it says no id found

when I search from a text file my program finds the record in c++, but once I terminate it and run it again it does not find the record, it says no id found,I also used arrays to store some of the detail.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
 #include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>

using namespace std;
int n=0;
int s=0;
class Employee{
  
  private:
  
  int EmployeeID[100];
  string EmployeeName[100];
  string EmployeeDateOfBirth[100];
  int EmployeeAge[100];
  string EmployeeGender[100];
  string EmployeeQualification[100];
  int EmployeeSalary[100];
  
  
  public:
  	void AddRecord();
  	void Search();
  	};
  	
    void Employee:: AddRecord(){
      	ofstream outfile;
		  outfile.open("Employee.txt",ios::app|ios::ate);
      	string cont;
      	do{
      	cout<<"Enter employee id:"<<endl;
      	cin>>EmployeeID[n];
      	
      	cout<<"Enter employee name :"<<endl;
      	cin>>EmployeeName[n];
      	
      	cout<<"Enter employee date of birth :"<<endl;
      	cin>>EmployeeDateOfBirth[n];
      
      	cout<<"Enter employee age :"<<endl;
      	cin>>EmployeeAge[n];
      	
      	cout<<"Enter employee gender:"<<endl;
      	cin>>EmployeeGender[n];
      
      	cout<<"Enter employee qualification :"<<endl;
      	cin>>EmployeeQualification[n];
      	
      	cout<<"Enter employee salary :"<<endl;
      	cin>>EmployeeSalary[n];
      	
      	cout<<"Do you want to continue adding employee records Y/N"<<endl;
      	cin>>cont;
      	n++;	
      	
      	}while(cont=="Yes"||cont=="yes"||cont=="Y"||cont=="y");
      		outfile<<"Employee id"<<setw(8)<<"Name"<<setw(16)<<"Date of birth"<<setw(10)<<" Age"<<setw(10)<<"Gender"<<setw(11)<<"qualification"<<setw(10)<<"salary"<<endl;
      		for(int a=0;a<n;a++)
      	outfile<<EmployeeID[a]<<setw(15)<<EmployeeName[a]<<setw(15)<<EmployeeDateOfBirth[a]<<setw(10)<<EmployeeAge[a]<<setw(10)<<EmployeeGender[a]<<setw(10)<<EmployeeQualification[a]<<setw(10)<<EmployeeSalary[a]<<endl;
          outfile.close();
        }
      
   void Employee::Search() { // for searching and modifiying data
	int s_id;
	int id, age; string name, gender,dob,qualification; double salary = 0.0;
	bool found = false;//holding value
	cout << "Enter Id to search" << endl;
	cin >> s_id;
    ifstream infile("Employee.txt",ios::app|ios::ate);
	for (int t = 0;t < sizeof(EmployeeID);t++) {
		if (s_id == EmployeeID[t]) {
			found = true;
			
			s_id = EmployeeID[t]; name = EmployeeName[t]; dob=EmployeeDateOfBirth[t];age = EmployeeAge[t]; qualification = EmployeeQualification[t]; salary = EmployeeSalary[t];
			cout << "**********RECOMMENDED ID***********" << endl;
			cout << "Id :" << id << "\nName : " << name << " " <<"\nDate of birth :"<<dob <<"  "<< "\nAge :" << age << " " << "\nQualification :" << qualification << " " << "\nSalary :" << salary << endl;
			n = t;
		}
	}
		if (found) {//change name if possible
			string choice2;
			string name;
			cout << "Do you want to change name y/n" << endl;
			cin >> choice2;
							if (choice2 == "y") {//y for changing name
					cout << "Enter new name" << endl;
					cin >> name;
					EmployeeName[n] = name;
					cout << "Name changed" << endl;}
							else {}
						
		}
		else { cout << "Id not found" << endl; }//no id
		ofstream outfile;
		outfile.open("Employee.txt",ios::app|ios::ate);
		for (int w = 0;w < s;w++) {
			outfile << "\n" << EmployeeID[w] << " " << EmployeeName[w] <<" "<<EmployeeDateOfBirth[w]<< ' ' << EmployeeAge[w] << " " << EmployeeGender[w] << " " << EmployeeQualification[w] << " " << EmployeeSalary[w];
		}
        outfile.close();
		}
		
   
       
      

      
	


/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main() {
	Employee emp;
	int choice;
	do{
	cout<<"Welcome to Employee Management System at Huki Online Solutions"<<endl;
    cout<<"1. Add Record"<<endl;
	cout<<"2. Search Record"<<endl;
	cout<<"3. Delete Record"<<endl;
	cout<<"4. List Record"<<endl;
	cout<<"5. Display Employment Hierarchy Based on salary"<<endl;
	cout<<"6. Exit"<<endl;
	cout<<"Enter option of your choice"<<endl;
	cin>>choice;
	
	if(choice==1)
	{
	  emp.AddRecord();
	  }
	  else if(choice==2)
	  {
	  	emp.Search();
	  }
	
	}while(choice!=6);
	return 0;
}
you do not use infile any where and if you did, you made it start at the eof, so it would not read anything. also you may or may not have troubles opening the same file twice.
I did not trace it but be sure you understand that to edit a text file you need to pretty much read it all in, edit the parts you want changed, and write it all back out. Edit in place is extremely tricky without fixed lengths: you can do it per line, with some care taken. Just in case you were trying to do it in place, again, I didn't read all that.
I don't how to read the program with eof and then search. I know I have to be able to read before I search.



Hello Vitrixvicto,

Sorry I came to realize this got bigger than I thought.

I made some changes and added some comments to your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <iostream>
#include <iomanip>
//#include <cstdlib>
#include <string>  // <--- Added. Needed for the "cin"s and "cout"s.

#include <fstream>

using namespace std;  // <--- Best not to use.

int n = 0;  // <--- Best not to use global variables.
int s = 0;

constexpr unsigned int MAXSIZE{ 100 };

class Employee
{
    private:  // <--- A class is private by default. The label is not necessary, but OK if you leave it.
        int EmployeeID[MAXSIZE];
        string EmployeeName[MAXSIZE];
        string EmployeeDateOfBirth[MAXSIZE];
        int EmployeeAge[MAXSIZE];
        string EmployeeGender[MAXSIZE];
        string EmployeeQualification[MAXSIZE];
        int EmployeeSalary[MAXSIZE];

    public:
        void AddRecord();
        void Search();
};

void Employee::AddRecord()
{
    ofstream outfile;
    outfile.open("Employee.txt", ios::app | ios::ate);  // <--- "app" is OK, but you do not need both.
    //ofstream outfile("Employee.txt", ios::app);  // <--- This is the more preferred way to define idx file stream and open the file at the same time.
    // <--- How do you know it is open. You should check here.

    string cont;

    do
    {
        cout << "Enter employee id: "; // <--- This puts the "cin" on the same line.
        cin >> EmployeeID[n];

        std::cin.ignore();  //<--- To eat the (\n) left in the buffer. Needed if formatted input is followed by "std::getline().

        cout << "Enter employee name: ";
        cin >> EmployeeName[n];  // <--- Using "std::getline()" would be a better choice for entering a string.

        cout << "Enter employee date of birth: ";
        cin >> EmployeeDateOfBirth[n];

        cout << "Enter employee age: ";
        cin >> EmployeeAge[n];

        std::cin.ignore();  // <--- Same as above.

        cout << "Enter employee gender: ";
        cin >> EmployeeGender[n];

        cout << "Enter employee qualification:";
        cin >> EmployeeQualification[n];

        cout << "Enter employee salary: ";
        cin >> EmployeeSalary[n];

        cout << "Do you want to continue adding employee records Y/N:";
        cin >> cont;

        n++;

    } while (cont == "Yes" || cont == "yes" || cont == "Y" || cont == "y");

    outfile << "Employee id" << setw(8) << "Name" << setw(16) << "Date of birth" << setw(10) << " Age" << setw(10) << "Gender" << setw(11) << "qualification" << setw(10) << "salary\n";

    for (int idx = 0; idx < n && idx < MAXSIZE; idx++)
        outfile
        << EmployeeID[idx]
        << setw(15) << EmployeeName[idx] 
        << setw(15) << EmployeeDateOfBirth[idx] 
        << setw(10) << EmployeeAge[idx] 
        << setw(10) << EmployeeGender[idx] 
        << setw(10) << EmployeeQualification[idx] 
        << setw(10) << EmployeeSalary[idx] << '\n';

    outfile.close();  // <--- Not required as the dtor will close the file when the function looses scope.
}

void Employee::Search()
{ // for searching and modifiying data
    int s_id{};  // <--- ALWAYS initialize all your variables.
    int id{}, age{};
    string name, gender, dob, qualification;
    double salary{};
    bool found{};  //holding value. Same as using "false".

    cout << "Enter Id to search: ";
    cin >> s_id;

    ifstream infile("Employee.txt"/*, ios::app | ios::ate*/);  // <--- "app" and "ate' are for output streams. Ignored when used with input streams

    for (int t = 0; t < sizeof(EmployeeID); t++)
    {
        if (s_id == EmployeeID[t])
        {
            found = true;

            s_id = EmployeeID[t]; name = EmployeeName[t]; dob = EmployeeDateOfBirth[t]; age = EmployeeAge[t]; qualification = EmployeeQualification[t]; salary = EmployeeSalary[t];

            cout <<
                "**********RECOMMENDED ID***********\n"
                "Id :" << id << "\nName : " << name <<
                "\n  Date of birth :" << dob << "  " << "\nAge :" << age << 
                "\n  Qualification :" << qualification << "\n  Salary :" << salary << '\n';

            n = t;  // <--- Guessing "n" is the amount of the array that is used? Why are you giving "n" new value here?
        }
    }

    if (found)
    {//change name if possible
        string choice2;
        string name;

        cout << "Do you want to change name y/n" << endl;
        cin >> choice2;

        if (choice2 == "y")  // <--- What about "Y"?
        {//y for changing name
            cout << "Enter new name: ";  // <--- Again using "std::getline()" would be a better choice for entering a string.
            cin >> name;

            EmployeeName[n] = name;

            cout << "Name changed\n";
        }
        else {}  // <--- If this is all you have it is not needed.

    }
    else { cout << "Id not found" << endl; }//no id

    ofstream outfile;
    outfile.open("Employee.txt", ios::app /*| ios::ate*/);
    // <--- How do you know? you should check.
    
    for (int w = 0; w < s; w++)
    {
        outfile 
            << "\n"
            << EmployeeID[w] << " " 
            << EmployeeName[w] << " " 
            << EmployeeDateOfBirth[w] << ' ' 
            << EmployeeAge[w] << " " 
            << EmployeeGender[w] << " " 
            << EmployeeQualification[w] << " " 
            << EmployeeSalary[w];  // <--- Should end with idx new line?
    }

    outfile.close();  // <--- Not required as the dtor will close the file when the function looses scope.
}


/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main()
{
    Employee emp;
    int choice{};  // <--- ALWAYS initialize all your variables.

    do
    {
        cout <<
            "Welcome to Employee Management System at Huki Online Solutions\n"
            "1. Add Record\n"
            "2. Search Record\n"
            "3. Delete Record\n"
            "4. List Record\n"
            "5. Display Employment Hierarchy Based on salary\n"
            "6. Exit\n"
            " Enter option of your choice: ";
        cin >> choice;

        if (choice == 1)
        {
            emp.AddRecord();
        }
        else if (choice == 2)
        {
            emp.Search();
        }

    } while (choice != 6);

    return 0;
}


End part 1.
Part 2:

When using "std::string" in a program DO NOT accept that "string EmployeeName[MAXSIZE];" is OK just because the IDE and compiler do not flagg it as an error. When you get to either "std::cin >> EmployeeName[idx]" or "std::cout << EmployeeName[idx]" you need the string header file so these 2 functions will know how to process the variable.

As nice as global variables are for ease access any line of code that follows them can change their value and it can be time consuming to track down where it went wrong. Consider making them a "static" public variable of the class. Or define them in "main" and pass them to the functions that need them.

You have used "std::ios::app" and "std::ios::ate" in your program. The both do the same thing, but "std::ios::ate" works with "std::ios::trunc", "app" does not.

Using "std::ios::app" with an "ifstream", if it not ignored by the compiler then it would put the file pointer at the ens and your first read would set the (eof) bit. Not what you want.

When you open a file stream for input or output you need to check that the file is open and usable. The best way is:
1
2
3
4
5
if (!inFile)
{
    return std::cout << "\n\n     File " << std::quoted(inFileName) << " did not open.\n", 1;  // <--- Requires header file "<iomanip>".
    //return std::cout << "\n\n     File \"" << inFileName << "\" did not open.\n", 1;
}


Line 38, defining this variable as a "char" would work better because at line 72 you have while (cont == "Yes" || cont == "yes" || cont == "Y" || cont == "y");. But what about "YES", "yeS", "yES" or something like "Yes more". Of course being formatted input it would stop at the 1st space and leave "more" in the buffer for whatever comes next for input. This could be a problem. Using a string for input you could check:
while (cont[0] == 'Y' || cont[0] == 'y');

From line 42 - 68 notice that I ended the prompt with "text: ". The space after the colon and lack of a (\n) or "endl" puts the input on the same line as the prompt.

I have no idea what the input would be for the variables defined as "std::string"s, but consider using "std::getline()" for these in case there may be a space in the input. Formatted input like std::cin >> EmployeeName[idx]; will stop at the first space it encounters and leave what may be left in the buffer for the next input which will through the rest of the input off and if you try to input a non numeric character into a numeric variable the "cin" would be in a failed state and unusable the rest of the program.

In the "Search" function:
In the for loop for (int t = 0; t < sizeof(EmployeeID); t++). Do you realize what the value of "sizeof(EmployeeID)" will return? "EmployeeID" is an "int" that would be 4 bytes and also an array of 100, so 4 * 100 = 400 bytes. Not what you are looking for.
 
sizeof(EmployeeID) / sizeof(EmployeeID[0])

would give you a size of 100 or you could just "MAXSIZE", but that is not what you want. The variable "n", a better name would help like "amtOfArrayUsed" or "amt Used" even "count" might work if the line "using namespace std;" does not cause a problem.

The if statement looks good at the moment, but I have not tested it yet. When the if statement becomes true you should end the block with "break;" to break out of the for loop because there is no point in going any farther.

In the next for loop I rearranged the "output" to make it easier to read. I noticed that you could make your life easier by setting up the output as:
1
2
3
4
5
6
7
8
9
10
11
12
for (int w = 0; w < s; w++)
{
    outfile 
        << "\n"
        << EmployeeID[w] << " " 
        << EmployeeName[w] << "," 
        << EmployeeDateOfBirth[w] << ',' 
        << EmployeeAge[w] << " " 
        << EmployeeGender[w] << "," 
        << EmployeeQualification[w] << "," 
        << EmployeeSalary[w];  // <--- I think this should end with a new line?
}

By adding a comma at the end of the strings you can use "std::getline" with the 3rd parameter set to (',') to read the stings.

In "main" you do not need a "cout" and "endl" for each line. Here the 8 line of quoted strings are considered 1 large string and the white space from the end of 1 string to the beginning of the next string is ignored by the compiler. The advantage here is that it looks much closer to what will be sent to the screen and also easier to edit, add, subtact a line or edit.

Your if/else if statement could easily be turned into a switch/case if you have studied that.

If I have missed something let me know.
Andy
Hello Vitrixvicto,

When I gave your program a test run I noticed the line of code:
 
outfile << "Employee id" << setw(8) << "Name" << setw(16) << "Date of birth" << setw(10) << " Age" << setw(10) << "Gender" << setw(11) << "qualification" << setw(10) << "salary\n";


Which would look more like this:
1
2
3
4
5
6
7
8
outfile 
    << "Employee id" 
    << setw(8) << "Name" 
    << setw(16) << "Date of birth" 
    << setw(10) << " Age" 
    << setw(10) << "Gender" 
    << setw(11) << "qualification" 
    << setw(10) << "salary\n";

The "std::setw()" works on what follows it not what precedes it.

Andy
As a first refactor, consider. This first reads the file (if present), then allows menu options and then re-writes the file with option 6 (exit). NB the outoput still needs tidying a bit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

class Employee {
private:
	const static inline size_t MaxRec {100};

	int EmployeeID[MaxRec] {};
	std::string EmployeeName[MaxRec];
	std::string EmployeeDateOfBirth[MaxRec];
	int EmployeeAge[MaxRec] {};
	std::string EmployeeGender[MaxRec];
	std::string EmployeeQualification[MaxRec];
	int EmployeeSalary[MaxRec] {};

	size_t norec {};

public:
	void AddRecord();
	void SearchRep();

	friend std::ostream& operator<<(std::ostream&, const Employee&);
	friend std::istream& operator>>(std::istream&, Employee&);
};

void Employee::AddRecord() {
	std::ofstream outfile("Employee.txt", std::ios::app);

	if (!outfile) {
		std::cout << "Cannot open output file\n";
		return;
	}

	std::string cont;

	do {
		std::cout << "Enter employee id: ";
		std::cin >> EmployeeID[norec];

		std::cout << "Enter employee name: ";
		std::getline(std::cin >> std::ws, EmployeeName[norec]);

		std::cout << "Enter employee date of birth: ";
		std::getline(std::cin, EmployeeDateOfBirth[norec]);

		std::cout << "Enter employee age: ";
		std::cin >> EmployeeAge[norec];

		std::cout << "Enter employee gender: ";
		std::getline(std::cin >> std::ws, EmployeeGender[norec]);

		std::cout << "Enter employee qualification: ";
		std::getline(std::cin, EmployeeQualification[norec]);

		std::cout << "Enter employee salary: ";
		std::cin >> EmployeeSalary[norec];

		if (++norec < MaxRec) {
			std::cout << "Do you want to continue adding employee records (Y/N): ";
			std::cin >> cont;
		}
	} while ( norec < MaxRec && (cont == "Yes" || cont == "yes" || cont == "Y" || cont == "y"));
}

void Employee::SearchRep() { // for searching and modifiying data
	bool found {};
	int s_id {};

	std::cout << "Enter Id to search: ";
	std::cin >> s_id;

	size_t n {};

	for (size_t t = 0; !found && t < norec; ++t) {
		if (s_id == EmployeeID[t]) {
			found = true;

			auto& id = EmployeeID[t];
			auto& name = EmployeeName[t];
			auto& dob = EmployeeDateOfBirth[t];
			auto& age = EmployeeAge[t];
			auto& qualification = EmployeeQualification[t];
			auto& salary = EmployeeSalary[t];

			std::cout << "**********RECOMMENDED ID***********\n";
			std::cout << "Id :" << id << "\nName : " << name << " " << "\nDate of birth :" << dob << "  " << "\nAge :" << age << " " << "\nQualification :" << qualification << " " << "\nSalary :" << salary << '\n';
			n = t;
		}
	}

	if (found) {
		std::string choice2;
		std::string name;

		std::cout << "Do you want to change name (y/n): ";
		std::cin >> choice2;

		if (choice2 == "y") {
			std::cout << "Enter new name: ";
			std::getline(std::cin >> std::ws, name);

			EmployeeName[n] = name;
			std::cout << "Name changed\n";
		}
	} else
		std::cout << "Id not found\n";
}

std::ostream& operator<<(std::ostream& os, const Employee& emp)
{
	for (size_t a = 0; a < emp.norec && os; ++a)
		os << emp.EmployeeID[a] << std::setw(15) << emp.EmployeeName[a] << ',' << std::setw(15) << emp.EmployeeDateOfBirth[a] << ','
		<< std::setw(10) << emp.EmployeeAge[a] << std::setw(10) << emp.EmployeeGender[a]
		<< std::setw(10) << emp.EmployeeQualification[a] << ',' << std::setw(10) << emp.EmployeeSalary[a] << '\n';

	return os;
}

std::istream& operator>>(std::istream& is, Employee& emp)
{
	emp.norec = 0;

	for (; emp.norec < emp.MaxRec && is; emp.norec += !!is) {
		is >> emp.EmployeeID[emp.norec];
		std::getline(is, emp.EmployeeName[emp.norec], ',');
		std::getline(is, emp.EmployeeDateOfBirth[emp.norec], ',');
		is >> emp.EmployeeAge[emp.norec] >> emp.EmployeeGender[emp.norec];
		std::getline(is, emp.EmployeeQualification[emp.norec], ',');
		is >> emp.EmployeeSalary[emp.norec];
	}

	std::cout << emp.norec << '\n';
	return is;
}

int main() {
	Employee emp;
	std::ifstream infile("Employee.txt");

	if (infile)
		infile >> emp;

	infile.close();

	int choice {};

	do {
		std::cout << "\nWelcome to Employee Management System at Huki Online Solutions\n";
		std::cout << "1. Add Record\n";
		std::cout << "2. Search Record/Replace\n";
		std::cout << "3. Delete Record\n";
		std::cout << "4. List Records\n";
		std::cout << "5. Display Employment Hierarchy Based on salary\n";
		std::cout << "6. Exit\n";
		std::cout << "\nEnter option: ";

		std::cin >> choice;

		switch (choice) {
			case 1:
				emp.AddRecord();
			break;

			case 2:
				emp.SearchRep();
				break;

			case 4:
				std::cout << emp << '\n';
				break;

			case 6:
				break;

			default:
				std::cout << "Invalid option\n";
		}

	} while (choice != 6);

	std::ofstream outfile("Employee.txt");

	if (!outfile)
		std::cout << "Cannot open file\n";
	else
		outfile << emp;
}

Last edited on
Topic archived. No new replies allowed.