My very first C++ program. (Uh-oh)

Started by
16 comments, last by NoobProger 16 years, 7 months ago
Ok I've been learning C++ for afew months now as my first lango ever - and with that said I took a stab at one of the exercises in a book I'm using. Keep in mind I'm still learning, and there are concepts I've already learned about but unable to apply in this program because well... I know of them, just not how to use them... if ya follow. So either way have a good laugh if ya want... The reason I'm posting this is to get help from you vets on how I could have make this program better, its really buggy... little things like typing a string to long to add to the list makes the program jump all over the place... adding more then 5 items to the list (you wouldn't be able to remove anything past 5 on the list, I didn't make the switch big enough... could I have used a enumerator here? I didn't get around to using int MAX_LIST yet either to limit the list size. saved that for verison 2.0 :X)

//gamelist.cpp
//the exercise asked that I make the following program use these functions.
//get a list started
//store a list
//remove items form a list
//display the list


#include <iostream>
#include <vector>
#include <string>

using namespace std;

vector<string> listv; // I know that declaring a global variable, like this is bad if over used.
vector<string>::iterator iter; //and that its not good practice - I plan to rewrite this whole thing.
//the reason I declare these is because I don't know how else to add to the vector (via in functions like main AND display)unless its declared here.
//if I declare it in the main function my display function cannot see it (keep in mind I'm still learning making functions of my
//own) and if I declare it in my function itself (display)I make a seperate list in that function... 
//I'm sure I might be able to user a pointer or something, but the problem is I still don't fully understand that.
//the reason I wrote this program was because of a book exercise that was given to me.  It is my very first time writing
//c++ code entirely by myself... with that said it barely works.  I've been learning C++ for afew months... first time
//learning any programming lango.
void display();

int main()
{
    //vector<string> listv; -commented out until I learn how to get my function to reference this.
    //vector<string>::iterator iter; -same as above.
    system("TITLE My very first - try not to laugh to hard.");
    string add;
    int MAX_LIST = 5;
    char add_another;
    char display_list;
    char remove_game;
    cout << "Welcome to the game list program\n";
    cout << "You'll be able to store games on the list, and remove them!\n";
    do
    {
         cout << "Type in the name of a game you liked to store it.\n";
         cin >> add;
         listv.push_back(add);
         system("CLS");
         cout << "GAME SAVED TO LIST!\n";
         cout << "Would you like to add another game to the list?[Y or N]\n";
         cin >> add_another;
    }while((add_another == 'Y') || (add_another == 'y'));
    
    cout << "Would you like to see your list of games?[Y or N]\n";
    cin >> display_list;
    if (display_list == 'y' || display_list == 'Y')
    {
                     system("CLS");
                     display();
                     }
    cout << "Now that you've got a list - would you like to remove any games?[Y or N]\n";
    cin >> remove_game;
    do
    {
                      char number;
                      system("CLS");
                      cout << "Which game would you like to remove?\n";
                      for (int i = 0; i < listv.size(); ++i)
                      cout << listv << endl;
                      cout << "Enter a number for the game that wasn't a good favorite\n";
                      cout << "If you are done removing games, type [done]\n";
                      cin >> number;
                   
                   switch(number)
                   {
                                 case '1':
                                      cout << "Deleting the first game listed.\n";
                                      listv.erase(listv.begin());
                                      break;
                                 case '2':
                                      cout << "Deleting the second game listed.\n";
                                      listv.erase(listv.begin() + 1);
                                      break;
                                 case '3':
                                      cout << "Deleting the 3rd game listed.\n";
                                      listv.erase(listv.begin() + 2);
                                      break;
                                 case '4':
                                      cout << "Deleting the 4th game listed.\n";
                                      listv.erase(listv.begin() + 3);
                                      break;
                                 case '5':
                                      cout << "Deleting the 5th game listed.\n";
                                      listv.erase(listv.begin() + 4);
                                      break;
                                 default:
                                         cout << "Invalid input - remove a item from the list.\n";
                                         cout << "using a number 1 - 5.\n";
                                         break;
                   }
                   cout << "Would you like to remove another?[Y or N]\n";
                   cin >> add_another;
    }while((add_another == 'Y') || (add_another == 'y'));     
    
    cout << "Here is a list of your finished favorites!\n";
    display();        
                            
    
    system("pause");
    return 0;
}
void display()
{
     cout << "Your current list!\n";
     for (int i = 0; i < listv.size(); ++i)
     cout << listv << endl;
}


[Edited by - NoobProger on September 3, 2007 12:06:48 PM]
09/03/07 - "I was feeling abit okward when I made the switch statement, like I was using a wrench to drive a nail into the deck, when I have a nice hammer right beside me... "
Advertisement
Quote:Oh yeah not to sure how to make one of them boxes to place my code into either - so I just simply pasted it right into the forum - sorry.
Put the code in [source][/source] tags (you can edit your original post using the 'edit' button in the upper right).
This is a very good first program..
I recognize many of the fundamental programming techniques you used.
Such as For, Do-While, Switch...

And though, I can't give you any constructive criticism on the code design..
(Since I don't know C++), I can at least tell you that you're getting pretty far!

Next think I would try to do (if I were you), is to use more object oriented design.
Like multiple classes and such. Keep up the good work.
Yeah the reason it is not OOP is because people told me it would be alot more simple if I learned the lango and worry about how to apply different programing styles later... they said don't worry about classes off the start... but as you said that is my next thing I'll be triyng to tackle.

Yeah I could have made the code abit more clearer and should have condenced alot of sections of it - but I wanted to apply alot of things I've already learned in my first program... I hear that its one thing to learn it, but its another to apply it.

I might have taken drivers-education to learn which pedals which, but you still have to learn to drive for yourself.

09/03/07 - "I was feeling abit okward when I made the switch statement, like I was using a wrench to drive a nail into the deck, when I have a nice hammer right beside me... "
Hi,

You seem to be aware of the global variables problem; are you aware you are polluting the global namespace by declaring "using namespace std" at the very top

A better solution would be to declare it inside the function where you commonly use it- else explititly declare the namespace with the variable/method you are using, that way you limit the namespace's scope.

Not essential stuff but nice to get into good habbits early on :) Good luck with the rest of your coding!
- Teach a programmer an answer, he can code for a day. Show a programmer the documentation, he can code for a lifetime.
This switch thingy is completely wrong ;). Why can't you simply make:

 cout << "Deleting the " << number << " game listed.\n";listv.erase(listv.begin() + number);

Quote:Original post by Shuger
This switch thingy is completely wrong ;). Why can't you simply make:

*** Source Snippet Removed ***



That was my first thought exactly, to get rid of the switch and make it flexible.
All in all, it looks really good. (A lot better than most of the "first C++ programs" around here)

Let me make a few changes in your program. Of course more could be done, but these are just a couple of modifications I think are good to get used to:

//gamelist.cpp#include <iostream> #include <vector>#include <string>// Only one of the following is needed, but I'm just including both here.#include <sstream> // We'll use std::stringstream later on, so we need the header for it#include <boost/lexical_cast.hpp> // Instead of stringstream, this is easier to use, but requires you to install the boost library// using namespace std; // This pulls everything from the std namespace into your global namespace. May cause conflicts (what if some other library also defined a string type?)// You're right, globals are bad, so let's put them where they belong.//vector<string> listv; // I know that declaring a global variable, like this is bad if over used.//vector<string>::iterator iter; //and that its not good practice - I plan to rewrite this whole thing.void display(); // Nice. Most beginners just cram everything into main(). Good to see you're using functions :)// There's still quite a bit of code that could be factored out into separate functions though. (Basically, anything you end up typing more than once is a good candidate for a function. And you have a lot of code that's duplicated, but you can probably spot them yourself :))int main(){    using namespace std; // It's safer to put it here. Then we're only polluting the namespace inside this function. You may want to remove this though, and prefix vector, cout, string and all other std types with std::// So the following line would have been std::vector<std::string>. That way you can be sure to avoid name collisions. Guess I'll do this in the display function, to show you both options :)    vector<string> listv; // Uncommented. We like local variables :)    vector<string>::iterator iter; //same as above.    system("TITLE My very first - try not to laugh to hard."); // Oh, never knew you could set the title of the console window like that. Fancy...     string add;    //const int MAX_LIST = 5; // By convention, only constants are ALL_CAPS. So might as well stick a const in there as well. Then it actually *acts* like a constant too.// That said, we don't actually need it (you don't even refer to it, and I plan to get rid of this limitation anyway, so just comment it out :)// Variables should be declared as close to where they're used as possible. So lets wait a bit with them. :)//    char add_another;//    char display_list;//    char remove_game;    cout << "Welcome to the game list program" << endl; // Note, I'm adding endl instead of \n. The former flushes the stream, so you're sure it's actually printed to the screen when this executes. Otherwise it may be buffered so it'll only show up later.    cout << "You'll be able to store games on the list, and remove them!\n";    do    {         cout << "Type in the name of a game you liked to store it.\n";         cin >> add;         listv.push_back(add);         system("CLS");         cout << "GAME SAVED TO LIST!\n";         cout << "Would you like to add another game to the list?[Y or N]" << endl;         char add_another; // Declare the variable here, where it's used.         cin >> add_another;    }while((add_another == 'Y') || (add_another == 'y'));        cout << "Would you like to see your list of games?[Y or N]\n";    char display_list; // Declare the variable here, where it's used.    cin >> display_list;    if (display_list == 'y' || display_list == 'Y')    {                     system("CLS");                     display(listv); // Here comes the magic bit. Pass the vector listv to the display function. That's all there is to it. :)                     }    cout << "Now that you've got a list - would you like to remove any games?[Y or N]\n";    char remove_game; // Declare the variable here, where it's used.    cin >> remove_game;    do    {                      //char number; // we need a string, not a char, because the user might type in big numbers that are more than one character                      string number;                      system("CLS");                      cout << "Which game would you like to remove?\n";                      for (int i = 0; i < listv.size(); ++i) { // Note the brackets. You don't *need* them when you only want to execute one line in the loop, but having them makes it clearer where the loop starts and ends (and saves you a lot of headaches if you later add more code to the loop, while forgetting to add brackets)                      cout << i << ": " << listv << endl; // I just made it print out the index as well, to make it easier for the user}                      cout << "Enter a number for the game that wasn't a good favorite\n";                      cout << "If you are done removing games, type [done]\n";                      cin >> number;                                      // Instead of the switch, you should get rid of the constant size limitation on your list, and simply parse the number entered by the user.                     // If you have the boost library installed (hint: Good idea. It can probably wait a few weeks though ;)), you can simply do this:                    int n = boost::static_cast<int>(number); // This doesn't take into account that the user might enter something that isn't a valid number because I'm lazy                     // Without boost, you'd do this instead:                     std::stringstream str(number);                     int n;                     str >> n; // Again, no error checking here, cos I'm lazy                    if (n > 0 && n < vlist.size()){ // Check that the number entered is greater than 0, and no bigger than the number of elements in the list                       listv.erase(listv.begin() + n);                    }                   cout << "Would you like to remove another?[Y or N]\n";                   cin >> add_another;    }while((add_another == 'Y') || (add_another == 'y'));             cout << "Here is a list of your finished favorites!\n";    display(listv);                                        //    system("pause"); // Is generally a bad idea (the user normally doesn't want the program to wait for him to press a key when exiting. While developing, you should just put a breakpoint here (which means you'll have to learn to use the debugger, and until you do that, there's no great harm in keeping this line of code. Just remember that it's only for development purposes. Once the application "ships", remove it to avoid driving your users mad... They paid for your program, after all, don't annoy them ;)    return 0;}void display(const std::vector<std::string>& listv) // And the other half of the magic. Without the &, it would simply receive a copy of the listv from the main function (so changes you made in this function wouldn't be saved No big deal, since you don't make any changes here. But & means it'll be given a reference to the original list instead (which is nicer all around, as it doesn't have to copy the list then). Note that it's const though, to indicate that you (the display function) promise not to make changes to the list. So combined, it means you're working on a reference to the original list (instead of a copy of the list), and you see the list as a constant, so you'll get errors if you try to modify it.{     std::cout << "Your current list!" << std::endl;     for (int i = 0; i < std::listv.size(); ++i) { // Again, I like {}'s around the loop body :)         std::cout << listv << std::endl;     }}


Of course, there are still things that could/should be changed, but you'll probably want to take it one step at a time. These are just the changes I think are interesting to start with.

(One particular part that'd need to be revised is the places where you read from cin. You need to do error handling when dealing with streams. The user might type in invalid values, and the stream has several error flags that should be checked. I consider that a tedious implementation detail though, and leave it to you [lol])

[Edited by - Spoonbender on September 3, 2007 3:12:02 PM]
Yes! This is the type of replies I wanted to see - and fast to. Thanks guys I'll be sure to look over them in more detail once I've got more time. (just quickly scan'd over them)

I was feeling abit okward when I made the switch statement, like I was using a wrench to drive a nail into the deck, when I have a nice hammer right beside me... :)

Also I didn't know I could use cout to set the title of the program as same with the system, just learned that little line of code from a random online tutorial. Nice to see you could just use cout also.

And declaring the variables right before use makes alot more sense... I kept scrolling to the top of main() to make sure I was using the correct name... tehehe. I'll get into the habbit of {}'s it also seems like good habbit.

that last function rewrite also cleared things up on how to reference a list. Thats what I was wondering, but I just couldn't remember the code needed to do the task - this mean I'm starting to get ready for a ref book? :D
Thanks again.
09/03/07 - "I was feeling abit okward when I made the switch statement, like I was using a wrench to drive a nail into the deck, when I have a nice hammer right beside me... "
Quote:Original post by NoobProger
I was feeling abit okward when I made the switch statement, like I was using a wrench to drive a nail into the deck, when I have a nice hammer right beside me... :)

Hehe, it's often a good idea to listen to those hunches. If something feels awkward, there probably is a better solution. :)

Quote:Also I didn't know I could use cout to set the title of the program as same with the system, just learned that little line of code from a random online tutorial. Nice to see you could just use cout also.

Oh, you wanted to set the title of the console window? My code just printed it out like any other text, since I wasn't sure what it was supposed to do. Ignore that part then [lol]

Quote:Thanks again.

No problem.

Also, out of curiosity, which book have you been using so far?

This topic is closed to new replies.

Advertisement