Creating a Program to Search an Index File Using the Command Line in Linux

Pages: 12
I have code that creates an index file created from a data file of records.

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
#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
#include <string>
#include <iomanip>

using namespace std;

class Record {
	string name;
	int code;
	double cost;
public:
	Record() {
	}
	Record(string tname,int tcode,double tcost) : name(tname),code(tcode),cost(tcost) { 
	}
	friend ostream& operator<< (ostream &os, const Record& r);
};

//print function
ostream& operator<< (ostream &os, const Record& r) {
	os << setw(10) << r.name << " " << setw(5) << r.code << " $"  << setw(10) << setprecision(2) << fixed << r.cost ;
	return os;
}
			
int main() {
	std::map<int, Record> myMap;
	ifstream data;
	size_t offset_count = 0;
	data.open("prog5.dat");
	ofstream outFile("prog5.idx", ios::out);
	
	//if file can't be opened, exit
	if(!data) {
		cerr << "Open Failure" << endl;
		exit(1);
	}
	
	std::string line;
	while (std::getline(data, line)) {
		stringstream ss(line);
		int key;
		string name;
		int code;
		double cost;
		
		if(ss >> key >> name >> code >> cost) {
			Record r(name,code,cost);
			myMap.insert( pair<int,Record>(key,r));
		}
		else {
			 cout << "Error";
		}
	}
	
	// print what's stored in map
	for(std::map<int,Record>::iterator x = myMap.begin(); x!=myMap.end(); ++x) {
		cout << setw(10) << x->first << ": " << x->second << endl;
	}
}


I now need to write a second program that allows the user to enter a command on the Linux command line such as

 
search 12382 prog5.idx


and returns the information for the record with that key. The code I included for the index file is correct and works properly, however I have no idea how to write the second program. Would anyone be able to help me out?

Here is the index file created by the first program:

1
2
3
4
5
6
7
8
9
         8:      blank     0 $      0.00
     12165:     Item16    30 $      7.69
     12345:     Item06    45 $     14.20
     12382:     Item09    62 $     41.37
     12434:     Item04    21 $     17.30
     16541:     Item12    21 $      9.99
     21212:     Itme31    19 $      8.35
     34186:     Item25    18 $     17.75
     41742:     Item14    55 $     12.36


The top line is a dummy record, the first number is the size of the file.
1) You need a code which loads file in some container of records.
2) You need to make use of the program arguments:

1
2
3
4
5
6
7
8
9
10
11
int main(int argc, char** argv)
{
    if(argc < 3) {
        std::cerr << "Too few arguments\n"
        std::exit(EXIT_FAILURE);
    }
    int key = atoi(argv[1]);
    const char* filename = argv[2];
    //Now use code from point (1), open file "filename"
    //and find record with key "key"
}
Thanks! On the "find record with key "key"" part, how would I go about doing that?

This is what I have so far, is it correct?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <prog3.idx>
#include <iostream>
#include <fstream>
using namespace std;

int main(int argc, char** argv) {
	if(argc < 3) {
		std::cerr << "Too few arguments \n";
		std::exit(EXIT_FAILURE);
	}
	
	int key = atoi(argv[1]);
	const char* filename = argv[2];
	filename.open("prog5.idx");
, is it correct?
No.
You cannot "open" a string (c-string)

you need: std::ifstream input(filename);
If you store records within map key:record as in example code, you can just do
std::cout << myMap.at(key);
Oh duh, I knew that. But you lost me at "If you store records within map key:record as in example code, you can just do std::cout << myMap.at(key); "
In case it's not clear, I really have no clue what I'm doing ha.
You have code which loads info from file to std::map<int, Record> myMap; (line 29) and saves it in slightly different format.

Now you need to modify code so it would load this new format you saved it as.
Then you would access your map as usual.
So to get the key from the user would I need to do something like this?

1
2
3
std::int key;
std::cout << "Enter a Key" << endl;
std::cin >> key;


And then do

 
std::cout << myMap.at(key);


to show the information?
I have no clue what to do with the map stuff, that part of the code was written with a lot of help.
So to get the key from the user would I need to do something like this?
No, you said you need to pass it in the comand line as search 12382 prog5.idx and so you need to use key variable you got when parsing program arguments. If you want to temporary take key from user (to test your program), then yes, you can do it.

And then do
std::cout << myMap.at(key);
to show the information?
Yes, pretty much. Note that this code will teminate a program (actually throw an exception) if key is invaid.
If you want to do something in case key is not found do following:
1
2
3
4
5
6
auto it = myMap.find(key);
if(key == myMap.end()) {
    std::cout << "Wrong key\n";
} else {
    std::cout << it -> second << '\n';
}
Ok I see. Still not sure what to do with the map stuff though :-/
Also, what type would "it" be in the example? I'm using an older compiler and it doesn't recognize auto.
Also, what type would "it" be in the example?
std::map<int, Record>::iterator
Ok I think I may finally have it right, however when I compile it I"m getting some errors, one of the main ones that's stumping me is this

1
2
program5.cpp:54: error: previous declaration ?int main()? here
prog5Search.cpp: In function ?int main(int, char**)?:


I know this is because I have two main methods, one in each file, but I'm not sure how to get around this? Any ideas?
I know this is because I have two main methods, one in each file, but I'm not sure how to get around this? Any ideas?
Delete main() which does not receive parameters. You do not need it. Program will use second main() as starting point.
Why don't you simply use (GNU) grep or (MS) findstr?
Ok, deleting main gives me the following 3 errors, any idea how I could correct them? They're all from the first program (program5.cpp) file.

1
2
3
program5.cpp:57: error: expected constructor, destructor, or type conversion before ?.? token
program5.cpp:61: error: expected unqualified-id before ?if?
program5.cpp:67: error: expected unqualified-id before ?while?
Last edited on
Because the directions were to create a separate program to search for a given key :-(
Well, you should not have two programs in one. Why didn't you started from new project?
It's in a separate file
Pages: 12