Beginner program ideas?

Hello! I recently started learning C++ with the tutorials over at http://www.learncpp.com, and I was looking for some ideas for programs I could make.

I just finished Chapter 5 of those tutorials, so that shows what I know so far.

Here are a few examples of programs I've made (which I'd really appreciate some feedback on!).

Rock, Paper, Scissors
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
// R,P,S V2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

float get1()
{
		cout << "Select 1, 2, or 3: ";
		float nChoice;
		cin >> nChoice;
		return nChoice;
}

float get2()
{
		cout << "Select 2nd choice: ";
		float nChoice2;
		cin >> nChoice2;
		return nChoice2;
}

int main ()
{
tryagain:
		cout << "Rock = 1, Paper = 2, Scissors = 3" << endl;

		float nChoice = get1();
		float nChoice2 = get2();

		if (nChoice == 1)
		{
			if (nChoice2 == 1)
				cout << "Choice 1 (" << nChoice << ") tied with Choice 2 (" << nChoice2 << ")!" << endl;
			if (nChoice2 == 2)
				cout << "Choice 1 (" << nChoice << ") lost to Choice 2 (" << nChoice2 << ")!" << endl;
			if (nChoice2 == 3)
				cout << "Choice 1 (" << nChoice << ") beat Choice 2 (" << nChoice2 << ")!" << endl;
		}

		if (nChoice == 2)
		{
			if (nChoice2 == 1)
				cout << "Choice 1 (" << nChoice << ") beat Choice 2 (" << nChoice2 <<")!" << endl;
			if (nChoice2 == 2)
				cout << "Choice 1 (" << nChoice << ") tied with Choice 2 (" << nChoice2 << ")!" << endl;
			if (nChoice2 == 3)
				cout << "Choice 1 (" << nChoice << ") lost to Choice 2 (" << nChoice2 << ")!" << endl;
		}

		if (nChoice == 3)
		{
			if (nChoice2 == 1)
				cout << "Choice 1 (" << nChoice << ") lost to Choice 2 (" << nChoice2 << ")!" << endl;
			if (nChoice2 == 2)
				cout << "Choice 1 (" << nChoice << ") beat Choice 2 (" << nChoice2 << ")!" << endl;
			if (nChoice2 == 3)
				cout << "Choice 1 (" << nChoice << ") tied with Choice 2 (" << nChoice2 << ")!" << endl;
		}
		else if (nChoice > 3 || nChoice < 1 || nChoice2 > 3 || nChoice2 < 1)
		{
			cout << "Error. Please enter valid choices!" << endl;
			cout << "" << endl;
			goto tryagain;
		}
		cin.get();
		cin.get();
		return 0;
}


Calculator V1 (This was my original, and I heavily modified it in the second version that I put below)

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
// Calculator.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;


char Op()
{
		cout << "Select " << endl;
		cout << "+ for addition" << endl;
		cout << "- for subtraction" << endl;
		cout << "* for multiplication" << endl;
		cout << "/ for division" << endl;

		openter:
		cout << "Please select an operator: ";
		char chOP;

		cin >> chOP;

		switch (chOP)
		{
			case '+':
				break;
			case '-':
				break;
			case '*':
				break;
			case '/':
				break;
			default:
				cout << "Error. Please enter a valid operator!" << endl << endl;
				goto openter;
		}

		check:

		cout << endl << "You selected " << chOP << "." << endl;
		cout << "Is this correct?" << endl;
		cout << "Y/N: ";

		char check;
		cin >> check;

		switch (check)
		{
			case 'N':
				cout << endl;
				goto openter;
			case 'n':
				cout << endl;
				goto openter;
			case 'Y':
				cout << endl;
				return chOP;
			case 'y':
				cout << endl;
				return chOP;
			default:
				cout << "Error. Please select N for no or Y for yes." << endl;
				goto check;
		}

}

float add()
{
		cout << "Addition" << endl << endl;
		cout << "Please enter first value: ";
		float AV1;
		cin >> AV1;

		cout << "Please enter second value: ";
		float AV2;
		cin >> AV2;

		float AR = AV1 + AV2;
		return AR;
}

float sub()
{
		cout << "Subtraction" << endl << endl;
		cout << "Please enter first value: ";
		float SV1;
		cin >> SV1;

		cout << "Please enter second value: ";
		float SV2;
		cin >> SV2;

		float SR = SV1 - SV2;
		return SR;
}

float multi()
{
		cout << "Multiplication" << endl << endl;
		cout << "Please enter first value: ";
		float MV1;
		cin >> MV1;

		cout << "Please enter second value: ";
		float MV2;
		cin >> MV2;

		float MR = MV1 * MV2;
		return MR;
}

float div()
{
		cout << "Division" << endl << endl;
		cout << "Please enter first value: ";
		float DV1;
		cin >> DV1;

		cout << "Please enter second value: ";
		float DV2;
		cin >> DV2;

		float DR = DV1 / DV2;
		return DR;
}

int main()
{
		char chOP = Op();

		if(chOP == '+')
		{
			float AR = add();
			cout << endl << "Result: " << AR << endl;
		}
		if(chOP == '-')
		{
			float SR = sub();
			cout << endl << "Result: " << SR << endl;
		}
		if(chOP == '*')
		{
			float MR = multi();
			cout << endl << "Result: " << MR << endl;
		}
		if(chOP == '/')
		{
			float DR = div();
			cout << endl << "Result: " << DR << endl;
		}

		cin.get();
		cin.get();
		return 0;
}


Calculator V2

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
// Calculator V2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;

float v1()
{
		cout << "Enter first number: ";
		float val1;
		cin >> val1;
		return val1;
}

char op()
{
		openter:

		cout << "Enter operator (+,-,* or /): ";
		char chOP;
		cin >> chOP;

		switch (chOP)
		{
			case '+':
				break;
			case '-':
				break;
			case '*':
				break;
			case '/':
				break;
			default:
				cout << "Error. Please enter a valid operator!" << endl << endl;
				goto openter;
		}
		return chOP;
}

float v2()
{
		cout << "Enter second number: ";
		float val2;
		cin >> val2;
		return val2;
}

int main()
{
		float val1 = v1();

		char chOP = op();

		float val2 = v2();


		cout << "You entered " << val1 << chOP << val2 << endl;

		cout << "Result: ";

		switch (chOP)
		{
			case '+':
				cout << val1 + val2;
				break;
			case '-':
				cout << val1 - val2;
				break;
			case '*':
				cout << val1 * val2;
				break;
			case '/':
				cout << val1 / val2;
				break;
		}

		cin.get();
		cin.get();
		return 0;
}



I can't wait for some ideas, thanks in advance!
Last edited on
closed account (NyhkoG1T)
Here is a google search that will give you a plethora of coding challenges

https://www.google.com/search?q=C%2B%2B+assignments+site%3A.edu&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
Last edited on
Great, thanks!

Could you provide some feedback for my programs I've made so far? Thanks!
The programs you've written above are pretty much what you'd expect from a beginner. As you continue to learn you'll have a more intimate understanding of what makes sense (in terms of program flow, structure and design, etc.), and you'll be able to consolidate and optimize your programs further and further.

Some more specific comments:

I see you ending your applications like so:

1
2
cin.get();
cin.get();


I'd like to suggest this instead:

1
2
std::cin.sync();
std::cin.get();


Additionally, I suggest that you remove the using namespace std; statement from the global scope. The only reason for using a using statement in your case is to be lazy, and because you're new you're not allowed to be lazy ;)
If you absolutely need to use it, put it in the most localized scope.

Also, you've got functions which look like this:

1
2
3
4
5
6
7
float v1()
{
		cout << "Enter first number: ";
		float val1;
		cin >> val1;
		return val1;
}


1
2
3
4
5
6
7
float v2()
{
		cout << "Enter second number: ";
		float val2;
		cin >> val2;
		return val2;
}


That seems very redundant. Why not write one function which you can use to pass any number as a reference? Why do you even need a function for that?

Also, I see this amongst your #includes:
#include "stdafx.h"
Perhaps you intentionally created your project with a precompiled header (I also don't know what IDE you're using, so it might be standard or something), but usually non-empty projects tend to introduce problems for beginners. There's nothing wrong with it, but it's not helping you, I think.

Also, think about giving your variables more appropriate names. I try to not use numbers in identifier names unless I would otherwise die, and it's pretty much standard to limit all-caps identifiers to #definitions or enums.
Also avoid goto statements and use loops instead.

Sorry, this sounds like a lecture. Just observations.

Last edited on
That's the precompiled header for visual studio or w.e all the newer people use for windows at school. I believe if you go under the settings you can remove the precompiled header.

*edit
Might I suggest using doubles instead of floats? They are twice as precise. Neither of them are precise though =p so if you are not using decimal digits I would suggest using shorts , long , long longs ( or int but most compilers it is default long you can use the macro to see which is the default if you wish )

Also a project you could do is make a "BigInt" class that would act like a precise double up to maybe 100 digits vs 8/16
Last edited on
I'd like to suggest this instead:

1
2
std::cin.sync();
std::cin.get();


The behavior of that code is implementation defined. sync is not required to do anything when invoked on an istream. I always cringe when I see people recommend it.
@cire Hmm? I hadn't realized there was something cringe-worthy about my suggestion. Could you either explain in detail or redirect me to a link so that I may see the error of my ways?
It's not portable and it may not work, as I already intimated with "sync is not required to do anything when invoked on an istream" (edit: which isn't technically true, but it is true that it isn't required by the standard to discard any input.)

http://www.daniweb.com/software-development/cpp/threads/90228/flushing-the-input-stream

Examples of it not working:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46624
http://ideone.com/zXmzqm
Last edited on
I see! Thank you for the links. I ought to do my research before I make bold suggestions ;)

Thanks Cire.
cin.sync() is not only formally implementation-defined, it's hard to justify logically: the purpose of sync() on an input stream is to make sure the temporary buffer that sits inside the istream object (std::cin in this case) matches (is synchronized with) the unprocessed input that is coming from the external device (keyboard in this case). Discarding the unprocessed input is not synchronizing!
Thanks for all the feedback, guys. I really appreciate it.

The reasoning behind the cin.get() (x2) was to prevent the program from automatically closing when run outside of VS.

I looked for a while for something to do this, and that was the only one I saw that worked.

What's a proper alternative?
std::cin.ignore(100, '\n');

or
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //must #include <limits>
@xismn
Additionally, I suggest that you remove the using namespace std; statement from the global scope.


The reasoning behind
using namespace std;
being in the global scope is as follows:

In my program 'Rock, Paper, Scissors', all the functions use cout/cin, which requires the 'using namespace std;'. It'd be pointless to place it individually in all the functions.

Also, both Calculator V1 and V2 use cout/cin in all of it's functions, so again, it'd be pointless to have 'using namespace std;' in all of the individual functions.


Furthermore, the reasoning behind the following:

float v1()
{
cout << "Enter first number: ";
float val1;
cin >> val1;
return val1;
}


&

float v2()
{
cout << "Enter second number: ";
float val2;
cin >> val2;
return val2;
}


is to get 2 different number inputs from the user (as the program is a calculator, and requires 2 numbers to do a calculation). I agree I poorly named these functions, but I am unaware of an alternative to get 2 different number inputs and refer to them as 'number 1' and 'number 2'. If you have an alternative, I'd definitely take it into consideration.

Lastly,
#include "stdafx.h"
is (as far as I know) a requirement with my IDE. It's automatically in the code when I start a new project.

I really appreciate your feedback, and I await your response.


Thanks!
Just as long as you know what you're doing, there's nothing wrong with a using namespace statement, however, especially in the global scope and especially with beginners, a using namespace statement has a tendency of introducing errors and name clashes.

One perfect example, though not in your code: std::distance.

That is why I suggested you remove the using namespace statement from the global scope, and place it in the local scope of any function which would benefit from it, as that would be good practice.

I will either edit this post, or submit a new post when I'm home.
In my program 'Rock, Paper, Scissors', all the functions use cout/cin, which requires the 'using namespace std;'.

No, it doesn't.

If you want to use cout/cin without the std:: prefix, you could use the using directives:

1
2
 using std::cout ;
using std::cin ; 


at the global scope, but there isn't a need to do that either. You could simply use the prefix.


Furthermore, the reasoning behind the following: [re: 2 nearly identical functions to get a floating point number]


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
#include <limits>
// ...

float getNum( const char* prompt )
{
    float input ;
    while ( std::cout << prompt && !(std::cin >> input) )
    {
        std::cin.clear() ;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') ;
        std::cout << "Invalid input!\n" ;
    }
    return input ;
}

// ...

int main()
{
    float val1 = getNum("Enter first number: ") ;

    char chOP = op();

    float val2 = getNum("Enter second number: ") ;

    // ... 
@cire

I appreciate the response.

That while loop with all the std::*stuff* is way over my head, but I appreciate the help.


Thanks!
I appreciate the response.

That while loop with all the std::*stuff* is way over my head, but I appreciate the help.


It shouldn't be. It's fairly basic input/output stuff with the console.

In pseudo code:
1
2
3
4
5
6
   while ( successful at displaying prompt and not successful at extracting a float value )
    {
        clear the error state on the input stream
        discard the input that caused us not to be able to extract a float value
        let the user know the input was invalid
    }


Technically, we don't care whether evaluation of the statement "std::cout << prompt" indicates success or not, since we normally just assume success, but keeping it in the condition means less redundant code. getNum could've looked like:

1
2
3
4
5
6
7
8
9
10
11
12
13
float getNum( const char* prompt )
{
    float input ;
    std::cout << prompt ;
    while ( !(std::cin >> input) )
    {
        std::cin.clear() ;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') ;
        std::cout << "Invalid input!\n" ;
        std::cout << prompt ;
    }
    return input ;
}

where you'll notice that line 4 and line 10 are identical.
Topic archived. No new replies allowed.