Sorting? Or Searching

Pages: 12345... 7
That's an appealing idea but you must read each item into the correct type of variable. You pretty much have to read the data member by member.

You can shorten and simplify the code somewhat by making GetData() a member function of the Details class. Unqualified member names can appear in a member function.
Last edited on

shouldn't this work? something is terribly wrong I would have thought that would cycle through the array and enter details through it.
Last edited on
File_Input>>DataEntry(Data[p]);

This definetly wont work?
You can shorten and simplify the code somewhat by making GetData() a member function of the Details class. Unqualified member names can appear in a member function.


I have no idea what this means? or what you want me to do
You can do this: File_Input>>Data[p]; but you need to define what ">>" means to a Details object.

A definition for >> would look like this:
1
2
3
4
5
6
7
8
9
10
11
istream& operator>>( istream& is, const Details& detail ) 
{
    is >> detail.FirstName;
    is >> detail.LastName;
    is >> detail.Age ;
    is >> detail.Email;
    is >> detail.DoorNumber;
    is >> detail.RoadName;
    is >> detail.PostCode;
    return is;
}

Then, File_Input>>Data[p]; will work.

Recall earlier when you asked "What do you mean by generalize?" and I answered "By overloading >> for a Details object so it can be read in like that."?

This is what I meant. I think it's the cleanest way to read the data from a file for a Details object.
Last edited on
I see. Does this go where functions are before int main.

also im having trouble understanding this (istream& is, const Details& detail)?

especially what istream& is means
1
2
3
4
5
6
7
8
9
10
11
12
13
14
istream& operator>>( istream& is, const Details& detail ){
    is >> detail.FirstName;
    is >> detail.LastName;
    is >> detail.Age ;
    is >> detail.Email;
    is >> detail.DoorNumber;
    is >> detail.RoadName;
    is >> detail.PostCode;
    return is;
	}
	for(int p=0;p<10;p++){
		File_Input>>Data[p]; 
		
	}


and ive tried it and it still doesn't work
(x86)\microsoft visual studio 10.0\vc\include\istream(429): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(long double &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\istream(447): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(void *&)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\istream(466): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::basic_streambuf<_Elem,_Traits> *)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> while trying to match the argument list '(std::istream, const std::string)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
long list of errrors that look like that
Yes, that code goes before int main.
istream is an "input stream" object. It could be a file input stream (ifstream), or it could be the input stream from the console (cin). File_Input will be passed as the "input stream" object 'is', and Data[p] would be passed as the Details object 'detail' to the operator>> function in this call:
File_Input >> Data[p];
In the operator definition istream& operator>>( istream& is, const Details& detail ) 'is' is the "left operand" and detail is the "right operand" in is >> detail

I know it's a big conceptual jump to overloading operators, but it is very useful.
And, the & in istream& means it is being passed "by reference" (so its value can be changed by the function) instead of by value (actually, not possible for a stream object. They are non-copyable).
Last edited on
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
void LoadData(Details &member){
	
	ifstream File_Input("test.txt");//Read test.txt
    if( File_Input.is_open()){
    
	cout <<"open";
	
	for(int p=0;p<10;p++){
		
	File_Input>>temp; 
	
	temp >> member.FirstName;
	temp >> member.LastName;
	temp >> member.Age;
	temp >> member.Email;
    temp >> member.DoorNumber;
    temp >> member.RoadName;
    temp >> member.PostCode;	
	}
    

	}
    else
    {
		ofstream File_Out("test.txt");//Create test.txt  
    }
}


ive also tried this but hit a dead end as I don't know how I can get it to cycle through each one eg first to name then last name then age etc.

visual studio doesn't like this for some reason
Last edited on
I don't see what you're trying to do there. What is temp and where did it come from?
I think that should be like this instead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void LoadData(Details info[], int size){
	
	ifstream File_Input("test.txt");//Read test.txt
    if( File_Input.is_open()){
    
	cout <<"open";
	
	for(int p=0;p<size;p++){		
	File_Input>>info[p];
	}
    

    }
    else
    {
		ofstream File_Out("test.txt");//Create test.txt  
    }
}

Actually, put the definition for operator>> before this function too.
Last edited on
removed.
Last edited on
I can't keep up with your posts.
I just saw this above:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
istream& operator>>( istream& is, const Details& detail ){
    is >> detail.FirstName;
    is >> detail.LastName;
    is >> detail.Age ;
    is >> detail.Email;
    is >> detail.DoorNumber;
    is >> detail.RoadName;
    is >> detail.PostCode;
    return is;
	}
	for(int p=0;p<10;p++){
		File_Input>>Data[p]; 
		
	}

You modified the code. Why? What you put in there makes no sense being there. (Back to the "one object is not itself 10 objects" thing.

I will post back soon to put it all together in one place for you. We've gotten a bit lost here.
Last edited on
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
Details Load;
	ifstream File_Input("test.txt");//Read test.txt
    if( File_Input.is_open()){
    
	cout <<"open";
	
	for(int p=0;p<10;p++){
		for(int q=0;q<7;q++){
		File_Input>>temp; 
	
		switch(p){
		case 1:temp >> Load.FirstName;break;
		case 2:temp >> Load.LastName;break;
		case 3:temp >> Load.Age;break;
		case 4:temp >> Load.Email;break;
		case 5:temp >> Load.DoorNumber;break;
		case 6:temp >> Load.RoadName;break;
		case 7:temp >> Load.PostCode;break;
		default:break;}
		}
    

	}
    else
    {
		ofstream File_Out("test.txt");//Create test.txt  
    }
}


my very own attempt ....
Last edited on
It's good to try what makes sense to you.

There was an error with the definition for operator>>. It was all about the const in
istream& operator>>( istream& is, const Details& detail ). This is wrong. My bad. It causes about 100 errors.

Here is the necessary code together in one place, so we can get on track here. It's getting late for me here.
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
class Details
{
public:
    Details();
    string FirstName;
    string LastName;
    int Age ;
    string Email;
    int DoorNumber;
    string RoadName;
    string PostCode;

};

Details::Details(): Age(0), DoorNumber(0) {}

// define operator >> for a Details object
istream& operator>>( istream& is, Details& detail )
{
    is >> detail.FirstName;
    is >> detail.LastName;
    is >> detail.Age ;
    is >> detail.Email;
    is >> detail.DoorNumber;
    is >> detail.RoadName;
    is >> detail.PostCode;
    return is;
}

void GetDetailsFromFile(Details Data[], int size)
{
    ifstream File_in("test.txt");// attempt to open file for reading
    if( File_in.is_open() )
    {
        for(int i=0; i<size; ++i)
            File_in >> Data[i];

        File_in.close();// details!
    }
    return;
}

void GetData(Details &member){
	cout << "\nFirst Name: "<< member.FirstName;
	cout << "\nLast Name: " << member.LastName;
	cout << "\nAge: " << member.Age;
	cout << "\nEmail: " << member.Email;
	cout << "\nDoor Number: " <<  member.DoorNumber;
	cout << "\nRoad Name: " << member.RoadName;
	cout << "\nPost Code: " <<  member.PostCode;
}

int main()
{
    Details info[10];
    // get the data from file
    GetDetailsFromFile( info, 10 );

    // let's see what we got
    for(int i=0; i<10; ++i)
        GetData( info[i] );

   return 0;
}

This builds error free for me. It should read 10 sets of values for Details objects from "test.txt", though it's hard to tell because that's all the program does. You could add code to output the Data[i] after the file read. Call your GetData() function.
EDIT: I added code for calling GetData.
Last edited on
Thanks for all the help. And it worked. Now just gotta understand why it work.
You're welcome.
Thank you for giving me something interesting to do during commercial breaks all day!

You made some big jumps with using classes. It may take a while to absorb.
Classes represent a powerful tool with many cool features.
I can foresee problems with the format of the data in the file.
It's already apparent from the sample presented earlier:
john
grace
20
johnman@hotmail.com
20
stcatherines
lu31ul

There are two related problems. One, individual pieces of data may contain spaces. UK postcodes are normally shown with a space, such as "LU3 1UL" and a street name may consist of several individual words, for example "St. Catherines Avenue".
Secondly, a piece of data may be missing. For example you may have a street address but no email, or vice versa.

A solution to both of these problems is to place all of the data for an individual on a single line in the file. Each item is separated by a delimiter, such as a comma or a tab.

Then, this function will change from this:
1
2
3
4
5
6
7
8
9
10
11
12
// define operator >> for a Details object
istream& operator>>( istream& is, Details& detail )
{
    is >> detail.FirstName;
    is >> detail.LastName;
    is >> detail.Age ;
    is >> detail.Email;
    is >> detail.DoorNumber;
    is >> detail.RoadName;
    is >> detail.PostCode;
    return is;
}

to this:
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
// define operator >> for a Details object
istream& operator>>( istream& is, Details& detail )
{
    string line;
    string word;
    char delim = '\t';
    getline(is, line);

    istringstream iss(line);

    getline(iss, word, delim);
    detail.FirstName = word;

    getline(iss, word, delim);
    detail.LastName = word;

    getline(iss, word, delim);
    detail.Age = atoi(word.c_str());          // convert string to integer

    getline(iss, word, delim);
    detail.Email = word;

    getline(iss, word, delim);
    detail.DoorNumber = atoi(word.c_str());   // convert string to integer

    getline(iss, word, delim);
    detail.RoadName = word;

    getline(iss, word, delim);
    detail.PostCode = word;

    return is;
}


That will handle data which looks like this, where '\t' is the tab character:
john\tgrace\t20\tjohnman@hotmail.com\t20\tSt Catherines Ave\tLU3 1UL\n


Of course this change will need to be mirrored in the code which outputs the data to the file. That change is relatively straightforward, simply outputting the tab delimiter between the items, and a single newline at the end of each record.

Note, the code I posted here could be shortened a bit. I left it like that to show what is going on.
Last edited on
so \t is a tab?
Pages: 12345... 7