functions

Hi I am new to cs and currently learning to use c++ this was an exercise we had in class the other day. I want to use ifstream to get data from a text file but I don't want it in my main as it is too long and untidy so I want to put it as a function which I can call and minimize the clutter

any suggestions are more then welcomed
thanks



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


int main()
{
	//welcomeMSG();// Welcome message and what the program does 
		//declare the necessary constants
	//create the Users and Contacts array of size 1000
	const int CAPACITY = 1000;
	int size = 0;
	float  user_ids[CAPACITY];
	float contact_with[CAPACITY];
	float contact_start[CAPACITY];
	float contact_end[CAPACITY];
	float distance[CAPACITY];
	float duration[CAPACITY];
	
	const int cap = 1000;
	int size2 = 0;
	float users_ids[cap];
	string fname[cap];
	string lname[cap];
	char gender[cap];
	int age[cap];
	int phone[cap];
	string address[cap];
	
	//read the files using the functions
	
	//function to read the contacts.txt file
	ifstream infile1; //Contact.txt
	infile1.open("contacts.txt");

	if (infile1.is_open())
	{
		string temp;
		float  id, cw, cs, ce, dist; //place holders 
		
		

		getline(infile1, temp);

		while (infile1 >> id >> cw >> cs >> ce >> dist)
		{
			
			user_ids[size]= id;
			contact_with[size]=cw;
			contact_start[size]=cs;
			contact_end[size]=ce;
			distance[size]=dist;
			size++;
		
		 //DEBUGGER 
		
		/*
			float dur = ce - cs;
			cout<< id << " " <<cw<< " " <<dur<< " " <<dist<<endl;
		*/
		

	
		}
	}
	else
	{
		cout << "Could not open" << endl;

	}
	
	//function to read the users.txt file
	ifstream infile2; //User.txt
	infile2.open("users.txt");
	
		if (infile2.is_open())
	{
		string temp2;
		float  u_id,u_age,u_phone;  
		string Fn, Ln, add;
		char  Gend;
		

		getline(infile2, temp2);

		while (infile2 >> u_id >> Fn >> Ln >> Gend >> u_age>>u_phone>>add) // Get the data from user text 
		{
			
		 users_ids[size2] = u_id;
		 fname[size2] = Fn;
		 lname[size2] = Ln;
		 gender[size2] = Gend;
		 age[size2] = u_age;
		 phone[size2] = u_phone;
		 address[size2] = add;
		 size2++;
	
		}
	}
	else
	{
		cout << "Could not open" << endl;

	}
	
	
	cout<< "\n\nselect your choice: \n";
	cout<< "\n\n1. Exit program \n";
	cout<< "\n\n2. Print users \n";
	cout<< "\n\n3. Print all the contacts \n";
	cout<< "\n\n4. Print all the contacts who came into contact \n";
	cout<< "\n\n5. Search by user ID \n";
	cout<< "\n"<<endl;
	cout<< "\n\n   Enter your option"<<endl;
	
	int op;
	cin >> op;
	if (op == 1 )
		return 0;
	
	// print funcs
	if (op == 2 )
	{
		PrintUsers( users_ids,  fname, lname, gender, age,  phone, address,  size2);//print users
	}
	if (op == 3 )
	{
		PrintContacts(user_ids,contact_with,contact_start,contact_end,distance, size);//print contacts
	}
	if (op == 4 )
	{
		CameIntoCon(user_ids,contact_with,contact_start,contact_end,distance, size);//print Con who came into contact
	}


//user_ids,contact_with,contact_start,contact_end,distance tags



//rest of the program…


	system("PAUSE");
	return 0;
}
Do you know about struct or class?

1
2
3
4
5
6
7
8
struct contact {
  float user_ids;
  float contact_with;
  float contact_start;
  float contact_end;
  float distance;
  float duration;
};


Then you can go onto say in main
 
contact contacts[CAPACITY];



With this, it's very easy to pass to functions
 
size = readContactsFile(contacts,CAPACITY,"contacts.txt");


Where
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
int readContacts(struct contact[], int capacity, const char *filename) {
	int size = 0;
	ifstream infile1; //Contact.txt
	infile1.open(filename);

	if (infile1.is_open())
	{
		string temp;
		float  id, cw, cs, ce, dist; //place holders 
		
		

		getline(infile1, temp);

		while (infile1 >> id >> cw >> cs >> ce >> dist)
		{
			
			contact[size].user_ids= id;
			contact[size].contact_with=cw;
			contact[size].contact_start=cs;
			contact[size].contact_end=ce;
			contact[size].distance=dist;
			size++;
		
		 //DEBUGGER 
		
		/*
			float dur = ce - cs;
			cout<< id << " " <<cw<< " " <<dur<< " " <<dist<<endl;
		*/
		

	
		}
	}
	else
	{
		cout << "Could not open" << endl;

	}
	return size;
}
Just a typo, you wrote
struct contact[]
but meant
struct contact contact[]
or something of that nature
Thanks guys but if I may ask how do I go about using the variables and accessing them
would it be

ie cout<<contact.contact_end....
or cout<< ce ?

but anyway thanks guys for help and if you have more feedback for on what else I can do I'll gladly appreciate it

> contact[size].user_ids= id;
Here is an example.

You can do things like
 
cout << contact[index].user_ids
As a first refactor, consider (NOT tried as no file data provided):

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

constexpr int CAPACITY {1000};

struct Contact {
	float  user_ids {};
	float contact_with {};
	float contact_start {};
	float contact_end {};
	float distance {};
	float duration {};
};

struct User {
	float users_id {};
	std::string fname;
	std::string lname;
	char gender {};
	int age {};
	int phone {};
	std::string address;
};

using Contacts = Contact[CAPACITY];
using Users = User[CAPACITY];

std::istream& operator>>(std::istream& is, User& user) {
	return is >> user.users_id >> user.fname >> user.lname >> user.gender >> user.age >> user.phone >> user.address;
}

std::istream& operator>>(std::istream& is, Contact& con) {
	return is >> con.user_ids >> con.contact_with >> con.contact_start >> con.contact_end >> con.distance;
}

std::ostream& operator<<(std::ostream& os, const User& user) {
	return os << user.users_id << "  " << user.fname << "  " << user.lname << "  " << user.gender << "  " <<
		user.age << "  " << user.phone << "  " << user.address << '\n';
}

std::ostream& operator<<(std::ostream& os, const Contact& con) {
	return os << con.user_ids << "  " << con.contact_with << "  " << con.contact_start << "  "
		<< con.contact_end << "  " << con.distance << '\n';
}

void PrintUsers(const Users users, int sz) {
	for (int e = 0; e < sz; ++e)
		std::cout << users[e] << '\n';
}

void PrintContracts(const Contacts con, int sz) {
	for (int e = 0; e < sz; ++e)
		std::cout << con[e] << '\n';
}

int main() {
	std::ifstream infile1("contacts.txt");
	std::ifstream infile2("users.txt");

	if (!infile1 || !infile2)
		return (std::cout << "Cannot open file\n"), 1;

	Contacts contacts;
	Users users;
	int size {}, size2 {};

	for (Contact con; size < CAPACITY && infile1 >> con; contacts[size++] = con);
	for (User user; size2 < CAPACITY && infile2 >> user; users[size2++] = user);

	for (int op {}; op != 1; ) {
		std::cout << "\n\nselect your choice: \n"
			<< "\n\n1. Exit program \n"
			<< "\n\n2. Print users \n"
			<< "\n\n3. Print all the contacts \n"
			<< "\n\n4. Print all the contacts who came into contact \n"
			<< "\n\n5. Search by user ID \n"
			<< "\n   Enter your option: ";

		std::cin >> op;

		switch (op) {
			case 1:
				break;

			case 2:
				PrintUsers(users, size2);
				break;

			case 3:
				PrintContracts(contacts, size);
				break;

			case 4:
				//CameIntoCon(user_ids, contact_with, contact_start, contact_end, distance, size);
				break;

			case 5:
				//SearchByuser();
				break;

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

Last edited on
parallel arrays are not always bad.
you can wrap those with the struct idea too..

float thing[maxsize];
float other[maxsize];
string text[maxsize];
... blah blah

struct magicwrapper
{
float* pthing;
float* pother;
string* ptext;
};
magicwrapper mw;
mw.pthing = thing;
mw.pother = other;
mw.ptext = text;
...
pass mw around..
foo(mw);
and inside foo..
mw.pthing[i]; //accesses thing[i]

if you want to go full on everything c++ offers tuple can replace the struct here and be directly constructed so the assignment setup part vanishes too. whole wrapper process shrinks to a couple of lines that way... when you have a lot of fields or a complex function, a reference inside foo can put names back on the parts if you want to clean it up a little.
Last edited on
ok Ive changed it quite a bit since last time and now using a struct. I want to use the members "contact_start and contact_end" to form duration

duration = contact_end - contact_start

any help is appreciated

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

//what the txt looks like
user_id contact_with contact_start contact_end   distance(cm)
1007    1010    	1630731125      1630731129      202

#include <iostream>
#include <fstream>
#include <string>
using namespace std;


//declare the Contact struct
struct Contact
{
	float user_id;
	float contact_with;
	float contact_start;
	float contact_end;
	float distance;
	float duration;

};



//functions to implement all the requirements (1-5)
float ContactDuration(cs,ce) // Calculate duration 
{

	for (int  i = 0; i < size; i++)
	{
		contacts[i].duration = contacts[i].contact_end - contacts[i].contact_start;
	}
	
	
	return contacts[i]->duration;

}
void PrintCameIntoCon(Contact contacts[], int size) // Print list of people who came into contact
{
	cout << "--------------------------------------------------------------------------------------------" << endl;
	cout << "UserID	Con/with	Duration	distance		" << endl;

	for (int i = 0; i < size; i++)
	{
		//float dur = ContactDuration(contacts[i].duration);
		//float dist = distance[i];

		while (contacts[i].duration>= 15 || contacts[i].distance <= 100)
		{
			cout << contacts[i].user_id << "	 " << contacts[i].contact_with << "		 " << contacts[i].duration << "		  " << contacts[i].distance << endl;
			break;

		}
	}
	cout << "--------------------------------------------------------------------------------------------" << endl;

}





int main()
{
	

	//Contacts
	const int CAPACITY = 1000;
	int size = 0;
	Contact contacts[CAPACITY];

	

	//read the files using the functions

	//function to read the contacts.txt file
	ifstream infile1; //Contact.txt
	infile1.open("contacts.txt");

	if (infile1.is_open())
	{
		string temp;
		float  id, cw, cs, ce, dist, dur; //place holders 

		getline(infile1, temp);

		while (infile1 >> id >> cw >> cs >> ce >> dist)
		{

			contacts[size].user_id = id;
			contacts[size].contact_with = cw;
			contacts[size].contact_start = cs;
			contacts[size].contact_end = ce;
			contacts[size].distance = dist;
			contacts[size].duration = ContactDuration(cs,ce,size);
			size++;
			
		}
	}
	else
	{
		cout << "Could not open" << endl;

	}

	


	cout << "\n\nselect your choice: \n";
	cout << "\n\n1. Exit program \n";
	cout << "\n\n2. Print users \n";
	cout << "\n\n3. Print all the contacts \n";
	cout << "\n\n4. Print all the contacts who came into contact \n";
	cout << "\n\n5. Search by user ID \n";
	cout << "\n" << endl;
	cout << " Enter your option" << endl;

	int op;
	cin >> op;

	switch (op) {

	case 1:
		break;

	case 2: {
		PrintUsers(users_ids, fname, lname, gender, age, phone, address, size2);//print users
		break;
	}



	case 3: {
		PrintContacts(contacts, size);//print contacts
		break;
	}



	case 4: {
		PrintCameIntoCon(contacts, size);//Print contacts with the conditions
		break;
	}



	case 5:
		//SearchByuser();
		break;

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

	//rest of the program…


	system("PAUSE");
	return 0;
}
you can add a function to structs themselves in c++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct Contact
{
	float user_id;
	float contact_with;
	float contact_start;
	float contact_end;
	float distance;
	float duration;
        float ContactDuration(){return contact_end - contact_start;}
};
main... ...
{
   stuff...
  cout <<  contacts[someindex].ContactDuration(); 
}


what you have uses a busted for loop... you loop over i, which is a loop variable that vanishes after the loop ends, but even if you moved i out to the function level, it would be out of bounds in the return statment as you just went 0-N in the loop and then i++ ends that loop at N+1 and then you ask for [i] which is out of range. It also seems to lack types on the function parameters and you don't pass the array in.
to fix what you have is probably

float ContactDuration(Contact * contacts, int index) // Calculate duration
{
return (contacts[index].contact_end - contacts[index].contact_start;
}

also notice that duration in the struct is never used (it is replaced by the function to compute it, in my example). if you think you must have it saved away, you can cook up something to keep it updated and then use it ...
Last edited on
Topic archived. No new replies allowed.