fstream inFile filter (super basic codes)

Hi, this is my first time posting here so if I violated any rules I am truly sorry.

I am a new CS student and I've been learning programming in C++ for almost 13 weeks, bare with me because I don't have much experience in anything and my codes are very very basic. So what I am trying to do right now is I have a file, and I know how to ifstream read file but how do I let the user input and filter out the numbers/subjects he wants to see from the file?

Example scenario:
I have a class of students each with different name, student IDs, studying in different grades, and have the same 7 subjects.
So I let the user input the grades and subjects that he wants to see. Then it will read the file and cout the matching students. So how do I do that?

Thanks in advance, hope to see simple solution since I have not learn about vector or anything. I have only learnt about function, iteration, input and output, arrays, strings and struct. I am using VS 2019 and programming in C++ language.
Last edited on
That depends entirely on the format/organization of the input file. So show the input.

Thinkable is a simplie loop like this:
1
2
3
4
5
6
7
8
9
10
std::cout << "What grade?\n";
std::cin >> find_grade;
while(in_file >> name >> id >> grade)
{
  if(grade == find_grade) // and subject?
  {
    std::cout << "Found " << name;
    break;
  }
}
Note that none of the input element (like name) can have white spaces. If that would be the case it would be more complicated.
What if I want the loop to cout the found statement? I tried replacing the cout inside the if loop with cout<<findgrade<<": "<<grade<<endl; but it doesnt cout anything.
Here's my 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
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main() {
	int C; //C for choice
	int Findform, form, FindSub;
	int BM, BI, BC, Math, Sci, Sejarah, Geo; //These are the subjects
	string id, name;
	ifstream readFile;

	cout << "Please select your choice: " << endl;
	cout << "	1.Filter" << endl;
	cout << "	2.Search" << endl;
	cout << endl;

	cout << "Choice:" << endl;
	cin >> C;

	if (C == 1) //Working on the filter option first.
	{
		cout << "Please key in the information that you want to filter." << endl;
		cout << "Form: " << endl;
		cin >> Findform;
		cout << "Subject: " << endl;
		cin >> FindSub;
		cout << "Filtered list:" << endl;
		readFile.open("student.txt"); //The texts inside the file is in the order inside while loop
		while (readFile >> id >> name >> form >> BM >> BI >> BC >> Math >> Sci >> Sejarah >> Geo);
		{
			if (Findform = form)
			{
				cout << "Student ID: " << id << endl;
				cout << "Student Name: " << name << endl;
				cout << "Form: " <<form<< endl;
				if (FindSub = BM)
					cout << FindSub << ": " << BM;
				if (FindSub = BI)
					cout << FindSub << ": " << BI;
				if (FindSub = BC)
					cout << FindSub << ": " << BC;
				if (FindSub = Math)
					cout << FindSub << ": " << Math;
				if (FindSub = Sejarah)
					cout << FindSub << ": " << Sejarah;
				if (FindSub = Geo)
					cout << FindSub << ": " << Geo;
				readFile.ignore();
			}
			
		}
	}
		
	system("PAUSE");
	return 0;
}


Much thanks to your generous reply! It does help me understand my question more!
Remove the last ; on L30. This says that the while loop has no body!

For the if statements, == is used for equality test. = means assignment!
So L32 should be:

 
if (Findform == form)


and similar for the other if statements.

Why L49? stream extraction ignores white space (space, tab, newline).
Last edited on
Thanks for correcting my careless mistake! But after these adjustments it still wouldn't cout anything after "Filtered list:" . Here's a sample of the text file.

21XXX0213
Adrian Choo
89 82 44 56 99 94 70
21ACV0231
Jenny Lee
67 90 66 54 98 74 81

etc.
The text file is stored in the same folder as the .cpp file. There's also no extra spacing after each line of text so I am wondering why it still wouldn't cout anything after the adjustments.

Also, I'm wondering if using function would make the codes easier to understand and shorter, I have the idea in my head but I couldn't make it work, any suggestions?

Thanks for your help in advance! I really do appreciate the replies and it helps me a lot in class!
Last edited on
if it does not print anything after filtered list, odds are, it failed to open that file.
you can prove this to yourself in the debugger or with some additional print statements, then try to figure out what is going on there.
some IDEs (visual specifically) change the working path behind your back, so a file that you think it would see may not be in the 'current folder' when it runs. On unix, the file name is case sensitive. There could be some other cause too, but those look likely.
Last edited on
It's not that simple. You try to store "Choo" in form which is an integer. While in name you store only "Adrian"

The operator>> exprects a white space as an sperator. So you may add

while (readFile >> id >> first_name >> last_name >> form

but it would be better to use getline(...) for the name. See:

http://www.cplusplus.com/reference/string/string/getline/?kw=getline
Thanks for the response! Currently I've tried solving the issue , and made some improvements. Now it does cout the statement but it still doesn't cout the marks for the subjects. And also if the user input multiple subjects in 1 input , how do I make sure the code filter also works in that way?
Notice that when you use std::getline(...) there is a potential problem when using with >>. See:

https://www.geeksforgeeks.org/problem-with-getline-after-cin/

And also if the user input multiple subjects in 1 input , how do I make sure the code filter also works in that way?
What are you trying to accomplish? I suggest that you show the code you have trouble with.

So below is the desired output. I don't know how to achieve it.

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

Inside the text file the writing format is like this
Student ID
Student Name
Grade(form)
BM BI BC Maths Sci Sejarah Geo

What I am having trouble right now is
1. The subject filter cannot cout anything
2. How do I make the code able to filter 2 subjects in 1 input ? (Subject(s): BC Sci)
Last edited on
If you look through these forums over the past few months you'll find a complete solution I posted.

Note that your sample input file doesn't correspond with what you want as it doesn't contain form numbers.
Last edited on
There are as always several ways to do this. The requirements seems to target std::getline(...), hence:
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
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main() {
	int C; //C for choice
	int Findform, form, FindSub;
	int BM, BI, BC, Math, Sci, Sejarah, Geo; //These are the subjects
	string id, name;
	ifstream readFile;

	cout << "Please select your choice: " << endl;
	cout << "	1.Filter" << endl;
	cout << "	2.Search" << endl;
	cout << endl;

	cout << "Choice:" << endl;
	cin >> C;

	if (C == 1) //Working on the filter option first.
	{
		cout << "Please key in the information that you want to filter." << endl;
		cout << "Form: " << endl;
		cin >> Findform;
		cout << "Subject: " << endl;
		std::getline(cin, FindSub); // Note: getline(...)
		cout << "Filtered list:" << endl;
		readFile.open("student.txt"); //The texts inside the file is in the order inside while loop
		while (readFile >> id >> std::ws) // Note: std::ws
		{
			std::getline(cin, name );

			if (readFile >> form >> BM >> BI >> BC >> Math >> Sci >> Sejarah >> Geo)
			{
			  if(Findform == form) // Note: ==
			  {
				cout << "Student ID: " << id << endl;
				cout << "Student Name: " << name << endl;
				cout << "Form: " <<form<< endl;
				if (FindSub.find("BM") != std::string::npos)
					cout << "BM: " << BM;
				if (FindSub.find("BI") != std::string::npos)
					cout << "BI: " << BI;
...
			  }
			}
		}
	}
		
	system("PAUSE");
	return 0;
}
Not tested!
Hi! Sorry for the late reply! I've been working on the code myself and I kind of succeeded on what I originally planned to do. In the end I basically scratched the whole code and did it from scratch again, which included struct and function parameters and definition . It made the whole code more understandable and it still works . And I decided to limit the user to only enter 1 subject to search instead of being able to enter multiple subject to search which would require to store the user input inside an array , I don't have the brains to do that lol.
Topic archived. No new replies allowed.