Menu oriented project problems

Pages: 12
Is any of this majorly wrong or just a few errors ? when i run it, it runs fine and displays the menu but, when i select 1 the program stops.I know have 7 prototypes and 7 options but I'm only working on the first one so far. It worked a few days ago but now when i select 1 as the menu choice it doesn't go to case 1 and then the case1() function.

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

using namespace std;	

int main();

int case1();
int case2();
int case3();
int case4();
int case5();
int case6();
int case7();

int main()
{
	fstream outFile;
	string fileName;
	string fileName1;
	char repeatMenu = 0;

	cout << "** MENU **" << endl << endl;
	cout << "Current Data File: " << fileName1;
	cout << endl << endl;


	do {

		int menuChoice;

		cout << "(1) Select / Create data file (.txt file extension will be added automatically)\n";
		cout << "(2) Display all numbers, total and average\n";
		cout << "(3) Display all numbers sorted\n";
		cout << "(4) Search for a number and display how many times it occurs\n";
		cout << "(5) Display the largest number\n";
		cout << "(6) Append a random number(s)\n";
		cout << "(7) Exit the program\n";

		cout << endl;

		cout << "Menu choice: ";
		cin >> menuChoice;

		if (menuChoice < 1 || menuChoice > 7)
		{
			do
			{
				cout << "Menu choice: ";
				cin >> menuChoice;
			} while (menuChoice < 1 || menuChoice > 7);
		}

		else
		{
			break;
		}

		cout << endl;

		switch (menuChoice)

		{
		
		case 1:

			int case1();
			break;

		case 2:

			ifstream fileName1;
			cout << endl;
			
		}

	} while (repeatMenu == 'Y' || repeatMenu == 'y');

	system("pause");
	return 0;
}

int case1()
{
	fstream outFile;
	string fileName;
	char repeatMenu;
	string fileName1;

	cout << "Name of data file: ";
	cin >> fileName;
	fileName1 = fileName + ".txt";
	cout << endl;

	if (outFile.fail())
	{
		cout << "The file did not open successfully.\n";
	}
	else
	{
		fstream outFile;
		outFile.open(fileName1);
		cout << "The file has been created successfully and/or opened successfully.\n" << endl;
	}
	
	
	cout << "Would you like to go back to the main menu ? [Y/N]: ";
	cin >> repeatMenu;
	if (repeatMenu == 'Y' || repeatMenu == 'y')
	{
		int main();
	}

	system("pause");
	return 0;
}

int case2()
{


	system("pause");
	return 0;
}
You have a problem on line 112: You are defining main() again: You leave a function you just need to return.
Line 55-58: else break is useless.

Line 68: This is a function prototype, not a function call. get rid of the int.

Line 112: It's illegal to call main recursively. BTW, this is also a function prototype, not a function call.

Lines 108-116: If you've completed what case1 is supposed to do, simply return back to main. Let main prompt for another menu selection.



Ooh alright thanks guys that helped a lot, but also in the case1() function in lines 91-105 when i prompt the user to select or create the name of a file, then i prompt to go back to menu [y/n] when i type y and it goes back to options, on line 25 how do i get it to carry over to display the name of the file the user has selected or created ? i tried adding << fileName1 but i guess that's not it.
What you're saying is that you want the filename to persist longer than the call to case1(). Therefore, you need to store the filename outside of case1(). Best way to do that is to declare a variable in main to hold it, then pass it by reference to case1().
Aren't i doing that on line 21 ? or is that out of scope ? if so how do i do that without a global variable ?
Aren't i doing that on line 21 ? or is that out of scope ?

Different scope. filename and filename1 are not used in main().

You need to delete line 87 and pass filename by reference to case1().
ooh okay like this ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int case1(string fileName,string fileName1)
{
	fstream outFile;
	char repeatMenu;

	cout << "Name of data file: ";
	cin >> fileName;
	fileName1 = fileName + ".txt";
	cout << endl;

	if (outFile.fail())
	{
		cout << "The file did not open successfully.\n";
	}
	else
	{
		fstream outFile;
		outFile.open(fileName1);
		cout << "The file has been created successfully and/or opened successfully.\n" << endl;
	}


but it also gives me 2 unresolved external errors so i dont think so, here are the errors

1>Source.obj : error LNK2028: unresolved token (0A0004D1) "int __cdecl case1(void)" (?case1@@$$FYAHXZ) referenced in function "int __cdecl main(void)" (?main@@$$HYAHXZ)

1>Source.obj : error LNK2019: unresolved external symbol "int __cdecl case1(void)" (?case1@@$$FYAHXZ) referenced in function "int __cdecl main(void)" (?main@@$$HYAHXZ)
Almost. As I said before, you need to pass filename by reference, so that when it is entered, it is changed in the caller. Otherwise if you pass by value as you're doing, you're operating on a copy of the filename and caller will never see any changes to it.

 
int case1 (string & fileName)


I would not bother passing filename1 since it is easily calculated.

Your undefined externals are due to your not changing your function prototypes, which also implies you did not change your call to case1() to pass filename.
Last edited on
Hope I'm at least closer than before to understanding this, now on line 67 it is saying too few arguments in function call. When i try adding (string fileName) , it tells me string is a type name that is not allowed.

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

using namespace std;	

int main();

int case1(string fileName);

int main()
{
	fstream outFile;
	string fileName1;
	char repeatMenu = 0;

	cout << "** MENU **" << endl << endl;
	cout << "Current Data File: " << fileName1;
	cout << endl << endl;


	do {

		system("cls");

		cout << "Current Data File: " << fileName1;

		cout << endl << endl;

		int menuChoice;

		cout << "(1) Select / Create data file (.txt file extension will be added automatically)\n";
		cout << "(2) Display all numbers, total and average\n";
		cout << "(3) Display all numbers sorted\n";
		cout << "(4) Search for a number and display how many times it occurs\n";
		cout << "(5) Display the largest number\n";
		cout << "(6) Append a random number(s)\n";
		cout << "(7) Exit the program\n";

		cout << endl;

		cout << "Menu choice: ";
		cin >> menuChoice;

		if (menuChoice < 1 || menuChoice > 7)
		{
			do
			{
				cout << "Menu choice: ";
				cin >> menuChoice;
			} while (menuChoice < 1 || menuChoice > 7);
		}

		cout << endl;

		switch (menuChoice)

		{
		
		case 1:

			case1();
			break;

		}

	} while (repeatMenu == 'Y' || repeatMenu == 'y');

	system("pause");
	return 0;
}

int case1(string fileName)
{
	fstream outFile;
	char repeatMenu;
	string fileName1;

	cout << "Name of data file: ";
	cin >> fileName;
	fileName1 = fileName + ".txt";
	cout << endl;

	if (outFile.fail())
	{
		cout << "The file did not open successfully.\n";
	}
	else
	{
		fstream outFile;
		outFile.open(fileName1);
		cout << "The file has been created successfully and/or opened successfully.\n" << endl;
	}
	
	
	cout << "Would you like to go back to the main menu ? [Y/N]: ";
	cin >> repeatMenu;
	if (repeatMenu == 'Y' || repeatMenu == 'y')
	{
		 main();
	}

	system("pause");
	return 0;
}
Closer.

Do you understand the difference between passing by value and by reference?
You're still passing filename by value. I showed you the syntax for passing by reference in my previous post. Note the underlined &.

Line 84: You're testing outfile for fail() before you attempt to open it.

Line 100: You're still attempting to make a recursive call to main(). As I indicated before, this is NOT allowed.

When i try adding (string fileName) , it tells me string is a type name that is not allowed.

Do not specify the data type when passing an argument on a function call.
It should be simply:
1
2
  case 1:  case1 (filename); 
               break;

I'm only a lil more than halfway through my semester of my first c++ class hah, i guess i don't quite understand passing by value and by reference yet then.

Like this you mean ? int case1(string & fileName)

As for line 84 is this it ?:
1
2
3
4
5
6
7
8
9
10
11
        fstream outFile;
	outFile.open(fileName1);

	if (outFile.fail())
	{
		cout << "The file did not open successfully.\n";
	}
	else
	{
		cout << "The file has been created successfully and/or opened successfully.\n" << endl;
	}


also I'm using line 100 to loop back into the main menu, before i was experimenting with goto's but couldnt find how to make them work and hear that they are bad anyways.

Also when i type fileName into case1() it gave me an undefined error, then i added it as a string variable again into main() and it gave me an overload error, same error when i add it as an argument into main(fileName):

IntelliSense: more than one instance of overloaded function "case1" matches the argument list:
function "case1(std::string fileName)"
function "case1(std::string &fileName)"
argument types are: (std::string)
Last edited on
Like this you mean ? int case1(string & fileName)

Yes.

As for line 84 is this it ?:

Yes.

also I'm using line 100 to loop back into the main menu

I understand what you're trying to do. My point is that it is specifically not permitted by the C++ standard and may result in undetermined behavior. As I pointed out much earlier in this thread, you should remove lines 96-102 and let main() worry about prompting for another menu choice. case1() should only select/create the data file. Nothing more.

when i type fileName into case1() it gave me an undefined error

Yes, you need to define fileName is main().

same error when i add it as an argument into main(fileName):

Why are you doing that?

IntelliSense: more than one instance of overloaded function "case1" matches the argument list:

Did you create multiple function prototypes for case1()? You should have only one.



I wanna wrap my head around this so damn badd, all the function names and arguments are the same but on line 60 case 1: case1(fileName); It has an error saying function does not take 1 arguments.


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

using namespace std;	

int main();
int case1(string & fileName);

int main()
{
	string fileName;
	fstream outFile;
	string fileName1;
	char repeatMenu = 0;

	cout << "** MENU **" << endl << endl;
	cout << "Current Data File: " << fileName1;
	cout << endl << endl;


	do {

		system("cls");

		cout << "Current Data File: " << fileName1;

		cout << endl << endl;

		int menuChoice;

		cout << "(1) Select / Create data file (.txt file extension will be added automatically)\n";
		cout << "(2) Display all numbers, total and average\n";
		cout << "(3) Display all numbers sorted\n";
		cout << "(4) Search for a number and display how many times it occurs\n";
		cout << "(5) Display the largest number\n";
		cout << "(6) Append a random number(s)\n";
		cout << "(7) Exit the program\n";

		cout << endl;

		cout << "Menu choice: ";
		cin >> menuChoice;

		if (menuChoice < 1 || menuChoice > 7)
		{
			do
			{
				cout << "Menu choice: ";
				cin >> menuChoice;
			} while (menuChoice < 1 || menuChoice > 7);
		}

		cout << endl;

		switch (menuChoice)

		{
		
		case 1:		case1(string & fileName);
						break;

		}

	} while (repeatMenu == 'Y' || repeatMenu == 'y');

	system("pause");
	return 0;
}

int case1(string & fileName)
{
	fstream outFile;
	char repeatMenu;
	string fileName1;

	cout << "Name of data file: ";
	cin >> fileName;
	fileName1 = fileName + ".txt";
	cout << endl;

	outFile.open(fileName1);

	if (outFile.fail())
	{
		cout << "The file did not open successfully.\n";
	}
	else
	{
		cout << "The file has been created successfully and/or opened successfully.\n" << endl;
	}

	system("pause");
	return 0;
}


Also before you said let the main function worry about looping back to itself but how would i do that after I'm inside other functions ?
Last edited on
Line 60: remove the string &. This is a function call. You do not specify argument types on a function call. Specify argument types only on function prototypes and function definitions.

Line 74: variable not used. Remove it.

Line 82: open needs a C-string. Use
 
  outFile.open (fileName1.c_str());


With those corrections, your program compiles cleanly.

how would i do that after I'm inside other functions ?

Simply return out of the other functions. main() already has a loop to handle prompting for another option.
Alright thank you it compiles nicely but, when choosing menu choice 1, naming data file "numbers", and cycling through program again, in Current data file: , it is still blank and doesn't display "numbers" or anything you name it. Here is correct version of program that loops:

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

using namespace std;	

int main();
int case1(string & fileName);
int case2();

int main()
{
	string fileName;
	fstream outFile;
	string fileName1;
	char repeatMenu = 0;

	do {

		system("cls");

		cout << "** MENU **" << endl << endl;

		cout << "Current Data File: " << fileName1;

		cout << endl << endl;

		int menuChoice;

		cout << "(1) Select / Create data file (.txt file extension will be added automatically)\n";
		cout << "(2) Display all numbers, total and average\n";
		cout << "(3) Display all numbers sorted\n";
		cout << "(4) Search for a number and display how many times it occurs\n";
		cout << "(5) Display the largest number\n";
		cout << "(6) Append a random number(s)\n";
		cout << "(7) Exit the program\n";

		cout << endl;

		cout << "Menu choice: ";
		cin >> menuChoice;

		if (menuChoice < 1 || menuChoice > 7)
		{
			do
			{
				cout << "Menu choice: ";
				cin >> menuChoice;
			} while (menuChoice < 1 || menuChoice > 7);
		}

		cout << endl;

		switch (menuChoice)

		{
		
		case 1:		case1(fileName);
			break;
		case 2:		case2();
			break;

		}

		cout << "Would you like to return to the main menu ? [Y/N]: ";
		cin >> repeatMenu;

	} while (repeatMenu == 'Y' || repeatMenu == 'y');

	system("pause");
	return 0;
}

int case1(string & fileName)
{
	fstream outFile;
	string fileName1;

	cout << "Name of data file: ";
	cin >> fileName;
	fileName1 = fileName + ".txt";
	cout << endl;

	outFile.open(fileName1.c_str());

	if (outFile.fail())
	{
		cout << "The file did not open successfully.\n";
	}
	else
	{
		cout << "The file has been created successfully and/or opened successfully.\n" << endl;
	}

	return 0;
}
I had to comment out lines 60 and 61 due to no implementation of case2().

When I ran this, I got "The file did not open successfully" until I created an appropriately named file. Then I got the success message.




Oohh i created a file for it a while ago and kept opening the same file, i just tried a different name and got what you got. I thought that

fstream filename;

filename.open();

not only opened a file but created one if one is not there ?

and also it's still not displaying the current data file on Line 24.
The documentation for fstream does not give any indication that a file is created if it does not exist:
http://www.cplusplus.com/reference/fstream/fstream/open/

Line 24: The first time through the loop, filename is empty because case1() has not been called yet. The name of the file should appear on a subsequent pass through the loop.
Oh okayy,

and i know it shouldn't/doesn't show the filename before i select the file but even after i name a file that i have previously created and run the loop Line 24 doesn't display the previously choosen filename.
Pages: 12