Searching and filtering a word in a text file

Can u help me with the filter and search code (c++)

1. Filter
2. Search
1. Teacher should be able to filter the list
through attribute of subjects and form.
2. Basic search function should be provided
for teachers to search based on any
keyword.
3. Display the results

This is the text file
Format of the text file:
Student ID
Student Name
Form
BM BI BC Math Sci Sejarah Geo

example of text file
20ACD1234
Alice Lim
1
80 93 78 75 86 82 67
20ACD1235
Derrick Tan
1
77 73 71 65 68 65 65
20ACD1236
Nelson Khoo
2
78 83 78 80 81 77 83
……
20ACD1237
Eric Tan
3
70 64 60 65 66 72 71

Example of output:

Please select your choice:
1. Filter
2. Search
Choice: 1
Please key in the information that you want to filter.
Form: 1
Subject(s): BC Sci
Filtered list:
Student ID: 20ACD1234
Student Name: Alice Lim
Form: 1
BC: 78
Sci: 86
Student ID: 20ACD1235
Student Name: Derrick Tan
Form: 1
BC: 71
Sci: 68
Do you want to continue?
Yes
Please select your choice:
1. Filter
2. Search

Choice: 2
Please key in the keyword you want to search: Alice
Search Results:
Student ID: 20ACD1234
Student Name: Alice Lim
Form: 1
BM: 80
BI: 93
BC: 78
Math: 75
Sci: 86
Sejarah: 82
Geo: 67
Last edited on
where is the code? We can't help with the code without seeing what you tried and an explain of where it isn't working.
Can u help me with the filter and search code

Code? What code? You've given us blurps of example input/output, but no code.

If'n you are expecting us to write it for you, not gonna happen.

We will assist you with code you write, not do the work for you.

Hello LookChicken,

When you get to posting code:

PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.

You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.



Now unless you want examples in the C++17 or C++20 standards it is best to post your code. This does not mean that you need to post the whole program, but enough code to compile and demonstrate what you have done and where youare having the problem.

Andy
Perhaps as a simple C++20 starter:

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
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <iterator>
#include <iomanip>
#include <vector>
#include <sstream>
#include <numeric>
#include <limits>
#include <cctype>
#include <type_traits>

template<typename T = int>
typename std::enable_if_t< std::is_integral_v<T>, T>
getInp(const std::string& prm)
{
	const auto notsp {[&]() {while (std::isspace(static_cast<unsigned char>(std::cin.peek())) && std::cin.peek() != '\n') std::cin.ignore(); return std::cin.peek() != '\n'; }};
	T n {};

	while ((std::cout << prm) && (!(std::cin >> n) || notsp())) {
		std::cout << "Invalid input. Not a(n) " << typeid(T).name() << '\n';
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return n;
}

template<typename T = int>
typename std::enable_if_t< std::is_integral_v<T>, T>
getInp(const std::string& prm, T low, T upper = std::numeric_limits<T>::max())
{
	T num {};

	do {
		num = getInp<T>(prm);
	} while ((num < low || num > upper) && (std::cout << "Input not in range\n"));

	return num;
}

constexpr const char* const subnames[] {"BM", "BI", "BC", "Math", "Sci", "Sejarah", "Geo"};

struct Student {
	std::string id;
	std::string name;
	unsigned form {};
	unsigned scores[std::size(subnames)] {};
};

using Students = std::vector<Student>;
using Reqs = std::vector<unsigned>;

std::istream& operator>>(std::istream& is, Student& s)
{
	if (is) {
		std::getline(is >> std::ws, s.id);
		std::getline(is, s.name);
		is >> s.form;

		for (size_t i = 0; i < std::size(subnames); ++i)
			is >> s.scores[i];
	}

	return is;
}

bool display(const Student& s, const Reqs& req)
{
	if (!req.empty()) {
		std::cout << "\nStudent ID: " << s.id << "\nStudent Name: " << s.name << "\nForm: " << s.form << '\n';

		for (const auto& r : req)
			std::cout << subnames[r] << ": " << s.scores[r] << '\n';

		return true;
	}

	return false;
}

bool display(const Student& s)
{
	Reqs req(std::size(subnames));

	std::iota(req.begin(), req.end(), 0);
	return display(s, req);
}

void display(const Students& stds)
{
	for (const auto& s : stds)
		display(s);
}

auto filter(const Students& stds)
{
	const auto fm {getInp<unsigned>("Form: ")};
	std::string subs;

	std::cout << "Subject(s): ";
	std::getline(std::cin, subs);

	std::istringstream iss(subs);
	Reqs req;

	for (std::string sub; iss >> sub;)
		if (const auto fidx {std::ranges::find(subnames, sub)}; fidx == std::end(subnames))
			std::cout << "Invalid subject - " << sub << '\n';
		else
			req.push_back(static_cast<unsigned>(std::distance(subnames, fidx)));

	size_t cnt {};

	for (const auto& s : stds)
		if (s.form == fm)
			cnt += display(s, req);

	std::cout << '\n';

	return cnt;
}

auto search(const Students& stds)
{
	std::string part;
	size_t cnt {};

	std::cout << "Enter partial name: ";
	std::getline(std::cin, part);

	for (const auto& s : stds)
		if (!std::ranges::search(s.name, part).empty())
			cnt += display(s);

	std::cout << '\n';

	return cnt;
}

int main()
{
	std::ifstream ifs("students.txt");

	if (!ifs)
		return (std::cout << "Cannot open input file\n"), 1;

	Students students;
	unsigned choice {};

	for (Student s; ifs >> s; students.emplace_back(s));

	do {
		std::cout << '\n' <<
			"1. Filter by form/subject(s)\n" <<
			"2. Search by partial name\n" <<
			"3. Display all students\n" <<
			"0. Exit\n\n";

		switch (choice = getInp<unsigned>("Choice: ", 0, 3);  choice) {
			case 1:
				std::cout << '\n' << filter(students) << " record(s) found.\n";
				break;

			case 2:
				std::cout << '\n' << search(students) << " record(s) found.\n";
				break;

			case 3:
				display(students);
				break;

		}
	} while (choice);
}

Last edited on
Topic archived. No new replies allowed.