• Advertisement

# C++ Small Projects

This topic is 3634 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

Could someone tell me how my code is? I'm just starting to learn code structure so there may be a bit too much spaghetti code. These are from the projects that Zahlman (sp?) recommended me. Thanks in advance! 1) "Hello World", or as at least one game programming book calls it, "Game Over". Just output a message.
#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
system("Title Hello World");
cout << "Hello world" << endl;
system("PAUSE");
return 0;
}

2) Get a line of text from the user and output it backwards. Try several approaches to the problem. Also try getting the "line" (probably only a word) from the command line arguments.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main(int argc, char* argv[]){
while(cin){
system("cls");
cout << "Enter text to output backwards:" << endl;
string input;
getline(cin, input);
stringstream ss(input);
string sInput;
if (ss >> sInput){
for (int i = sInput.length(); i >= 0; --i)
cout << input;
}else{
cout << "Invalid input!" << endl;
}
cout << endl;
system("PAUSE");
}
}

3) Prompt for two numbers and report the product. Add in all the appropriate error handling: for each number, repeatedly ask until you actually get a valid number. Read the standard input a line at a time for this, and ignore any "garbage" text that appears after a valid number on the line (but do complain about garbage at the beginning).
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
while(cin){
system("CLS");
cout << "Enter 2 numbers to multiply:" << endl;
string sInput;
getline(cin, sInput);
stringstream ss(sInput);
float fFirst, fSecond;
if (ss >> fFirst >> fSecond)
cout << fFirst << " * " << fSecond << " = " << fFirst * fSecond << endl;
else
cout << "Incorrect input!" << endl;
system("PAUSE");
}
}

4) Guess the number.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <ctime>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
srand((unsigned)time(0));
int iNumber = (rand()%100);
int iTries = 0;

while(cin){
system("CLS");
cout << "Guess the number! The number is between 0 and 100." << "\n" << endl;
string sInput;
getline(cin, sInput);
stringstream ss(sInput);
int iGuess;
if (ss >> iGuess){
if (iGuess > iNumber){
cout << "Guess lower!" << endl;
++iTries;
}else if (iGuess < iNumber){
cout << "Guess higher!" << endl;
++iTries;
}else if (iGuess = iNumber){
cout << "You are CORRECT!" << " The number was " << iNumber << " and that took " << iTries << " tries." << endl;
system("PAUSE");
return 0;
}
}else
cout << "Bad Input!" << endl;

cout << "\n";
system("PAUSE");
}
}

5) Rectangle blitter: Ask for an x-position, y-position, width, height, and symbol, and draw a corresponding rectangle filled with that symbol onto the console. Assume that the first character you output will appear at the top-left of the console window; output enough characters to fill one screen of the console. You don't get full marks until you have robust error handling. Note: if part of the rectangle would be off-screen, make sure you only draw the on-screen part. (It is ok if none of it is on screen; just output a whole field of spaces.)
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
while(cin){
system("CLS");
cout << "Enter an x-position, a y-position, and a symbol:" << endl;
string sInput;
getline(cin, sInput);
stringstream ss(sInput);
int iX_Position, iY_Position;
string sSymbol;
if (ss >> iX_Position >> iY_Position >> sSymbol){
if (sSymbol.length() > 1){
cout << "The symbol must be a single character!" << endl;
}else{
for (int z = 0; z < iY_Position; ++z){
for(int x = 0; x < iX_Position; ++x)
cout << sSymbol;
cout << endl;
}
}
}else
cout << "Bad input!" << endl;
system("PAUSE");
}
}

6) Mad Libs. Read an input file that contains placeholders marked by square brackets (you may assume there are no other instances of square brackets in the file). As you read not-enclosed text, append it to an output string. When you find a square bracket, read the text between the square brackets (it will be some kind of description, like "proper noun") and prompt the user to supply something of that sort. "Fill in the blank" by appending it to the output string. Once you reach the end of the file, output the whole output string.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
string sFinal;
ifstream libfile ("madlibs.txt");
if (libfile.is_open()){
while (!libfile.eof()){
string sCurrentWord;
string sUserline;

libfile >> sCurrentWord;
string::size_type loc = sCurrentWord.find( "[", 0 );
if( loc != string::npos ) {
cout << sCurrentWord;
cin >> sUserline;
sFinal.append(sUserline + ". ");
} else {
cout << sUserline;
cout << sCurrentWord << " ";
sFinal.append(sCurrentWord + " ");
}
}
libfile.close();
}
else
cout << "The file cannot be opened!";

cout << sFinal;

system("PAUSE");
return 0;
}

7) Hangman. This isn't necessarily harder than Mad Libs, but it's more like a "complete game". Read in a word list from a file. Ensure that there are no arbitrary limitations on how many words there are, and pick a random word each game (make sure you are using the srand() properly).
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

int LineNumber(void)
{
int iLineCount = 0;
string sCurrentWord;
ifstream libtestfile ("Hangman.txt");
if (libtestfile.is_open()){
while (!libtestfile.eof()){
libtestfile >> sCurrentWord;
++iLineCount;
}
}else
cout << "The test file cannot be opened!" << endl;

srand((unsigned)time(0));
int iRandomNumber = (rand()%iLineCount + 1);
return (iRandomNumber);
}

int _tmain(int argc, _TCHAR* argv[])
{
int iLineSelect;
iLineSelect = LineNumber();
string sCurrentWord;
string sChosenWord;
int iLineNumber = 0;
ifstream libfile ("Hangman.txt");
if (libfile.is_open()){
while (!libfile.eof()){
libfile >> sCurrentWord;
++iLineNumber; // increases the line number
if (iLineNumber == iLineSelect){ // if the line count is the same as the chosen number
sChosenWord = sCurrentWord; // The word is chosen is the current word
cout << "A word has been chosen that has " << sChosenWord.length() << " characters, now guess a character!" << endl;
cout << endl;
break;
}
}
libfile.close();
}
else
cout << "The file cannot be opened!" << endl;
string sLetters;
int iTally = 0;
int count = 0;
while(cin){
string sInput;
getline(cin, sInput);
stringstream ss(sInput);
string sGuess;
if (ss >> sGuess){
if (sGuess.length() > 1)
cout << "You can only guess 1 letter..." << endl << endl;
else{
string::size_type loca = sLetters.find(sGuess);
if( loca != string::npos ) {
cout << "You already guessed that letter..." << endl << endl;
}else{
for (std::string::size_type i = 0; i < sChosenWord.size(); ++i) {
if (sChosenWord == sGuess[0]){
++count;
for (int i = 0; i < 1; ++i){
cout << "Yes, the word has " << count << " " << sGuess << "." << endl <<
endl;
}
}
}

string::size_type loc = sChosenWord.find(sGuess);
if( loc == string::npos ) {
cout << "No, the word does not contain the character " << "'" << sGuess << "'" << "." << endl;
++iTally;
switch(iTally){
case 1:
cout << "Your head has been drawn, 5 chances left." << endl << endl;
break;
case 2:
cout << "Your body has been drawn, 4 chances left." << endl << endl;
break;
case 3:
cout << "Your left arm has been drawn, 3 chances left." << endl << endl;
break;
case 4:
cout << "Your right arm has been drawn, 2 chances left." << endl << endl;
break;
case 5:
cout << "Your left leg has been drawn, 1 chance left." << endl << endl;
break;
case 6:
cout << "Your right leg has been drawn, you LOSE!" << " The word was " << "'" << sChosenWord << "'" << "." << endl;
system("PAUSE");
return 0;
break;
default:
cout << "!" << endl;
}
}
if (sChosenWord.length() == count){
cout << "You WIN! The word was " << "'" << sChosenWord << "'" << "." << endl;
system("PAUSE");
return 0;
}
sLetters.append(sGuess);
}
}
}
}
system("PAUSE");
}


#### Share this post

##### Share on other sites
Advertisement
1) system() is not cross-platform. Not "wrong", per se, and if you don't care, that's fine.
2) getline(cin, input); is probably not the most "C++-ey" thing to do... why don't you just do cin >> input? And I'm assuming that string->stringstream->string again is error checking of some kind? Highly resourceful... but there may be an easier way... *cough* Won't comment on the while (cin), other than to say it's not how I would have done it... which, again, doesn't mean it's wrong.
3) You don't complain about the "garbage", I note, which is in Zahlman's spec, although you do avoid it nicely. It also looks as though each number can only be 1 digit, which is counter-intuitive. Try adding multi-digit support. (NOTE: This may already work... I don't know enough about stringstreams to be able to tell for sure)
4) Looks good to me.
5) Don't you think you should separate the requests? Makes the input easier to handle, and helps not to confuse the user. Also, unless I'm mistaken, you assume that if something's the wrong length, it'll be the symbol. What if X or Y are too long? Missing? What if X or Y are entered as characters (other than 0-9)?
6) On this one I'm gonna need some clarification of intent (comments are good things, btw... even if you think you're the only one who's going to read the code. Get into the habit now, it'll help you later). Why are you outputting a period after each user-input? Are user-inputs only at the end of sentences? Also, are you cout-ing the words twice (when you read them and as part of the output string)? That's what it looks like to me without testing your code, anyway.
7) If you're doing C++, then the proper way to declare a function with no arguements is foo(), not foo(void). Void works, but it's ugly.
If you can't open the file, you're still going to run the rest of the program... you need to return something from the main() function to quit the program.
Your "Yes, the word has" statement should not be wrapped in a for loop. And that "loop" would only run once, in any case.
Why not use find to check if the word contains the guess BEFORE looping through the word?
That's all I see for now... How thoroughly did you test your code? A good test cycle is a programmer's best friend. Comments are helpful too.

If you have any questions, feel free to PM or e-mail me, and I'll do my best to help.

[Edited by - EmrldDrgn on March 14, 2008 11:48:08 PM]

#### Share this post

##### Share on other sites
Quote:
 Original post by EmrldDrgn5) Don't you think you should separate the requests? Makes the input easier to handle, and helps not to confuse the user. Also, unless I'm mistaken, you assume that if something's the wrong length, it'll be the symbol. What if X or Y are too long? Missing? What if X or Y are entered as characters (other than 0-9)?

If X or Y are missing it outputs "bad input!". I don't assume that if something is the wrong length, it'll be the symbol. The symbol is the third entry. For example: if the user enters "23 10 *", X will be 23, Y will be 10, * will be the symbol. The symbol must be a single character, however, which is probably what got you mixed up. Thanks for the help, I'll take note!

#### Share this post

##### Share on other sites
Actually what messed me up was that if a stringstream contains "56" and you do ss >> someInt;, the int now contains 56, not 5. As I said, stringstream's not really my forte. I had just realized this and gone back to correct my above post when I saw yours... my apologies.

NOTE: My point about separating input is emphasized here... it avoids such confusion. Your user may be frustrated that "2535 *" doesn't work, while "25 35 *" does.

#### Share this post

##### Share on other sites
Quote:
 Original post by EmrldDrgnActually what messed me up was that if a stringstream contains "56" and you do ss >> someInt;, the int now contains 56, not 5. As I said, stringstream's not really my forte. I had just realized this and gone back to correct my above post when I saw yours... my apologies.NOTE: My point about separating input is emphasized here... it avoids such confusion. Your user may be frustrated that "2535 *" doesn't work, while "25 35 *" does.

Yes, I understand. I'll revise it to make it more user-friendly. Thanks for your advice and no need to apologize!

#### Share this post

##### Share on other sites
Quote:
Original post by rippingcorpse
Quote:
 Original post by EmrldDrgnActually what messed me up was that if a stringstream contains "56" and you do ss >> someInt;, the int now contains 56, not 5. As I said, stringstream's not really my forte. I had just realized this and gone back to correct my above post when I saw yours... my apologies.NOTE: My point about separating input is emphasized here... it avoids such confusion. Your user may be frustrated that "2535 *" doesn't work, while "25 35 *" does.

Yes, I understand. I'll revise it to make it more user-friendly. Thanks for your advice and no need to apologize!

No problem. I added the last two programs, as well. Happy to help.

#### Share this post

##### Share on other sites
Quote:
 Original post by EmrldDrgnwhy don't you just do cin >> input?

Probably because he wants to read an entire line, cin >> input will only read up to the first white space it hits.

Actually this leads to to problem in 2). You read an entire line of text from cin but then you use the >> operator to get data out the of the stringstream. So your program only actually reverses one word rather than a line.

#### Share this post

##### Share on other sites

• Advertisement
• Advertisement
• ### Popular Tags

• Advertisement
• ### Popular Now

• 45
• 11
• 17
• 11
• 13
• Advertisement