Program Stops Working - Not Sure How to Fix it

Hi guys,

I'm creating a blackjack game (for the final project of my c++ class), and it had been going fine up until now.

I have three functions running in succession without any user input - a function that randomly selects cards for the dealer and the user, a function that draws the dealer's cards, and a function that draws the user's cards. After these are all run, a fourth function should run, asking the player if they would like to hit or not.

However, none of the text that I cout in the fourth function ever appears. It stops working right at the end of the last card that is drawn, and refuses to move any further in the program.

Curiously, if I use the clear screen program ( it resets the cursor, clears the screen, and flushes the cout) I have included, at the beginning of the fourth loop, it runs fine.

I'm using Visual C++ 6.0 (if that helps), and I can post the source code if you guys want, but I was leaning against that right off the bat as there's a lot of it to look through....


Any Ideas?

I am interested in helping you out in this. Can you post some more details.
Okay, I tried to pull out the most relevant source code, it's nowhere near all of it - more like 1/2 way through the program, so let's see how this goes:

-code is now in post below-

The first function is the one that all of the others are accessed from, the program hangs in between the 3rd and 4th functions (it is noted where in the code). I'm assuming it's due to some sort of overload with the I/O stream, as using the clear screen program (which I referenced earlier) at the beginning of the 4th function allows that code to be executed.
Last edited on
You'd be better off putting that in pastebin, it's a bit on the long side for the threads.
So where's main?
Okay, here's the link to the pastebin, let's try that... I have the line highlighted where you should start caring.

http://pastebin.com/m21464f91
I've been playing around with it a tiny bit, and here are my preliminary suggestions.


standard headers

Don't use things like <iostream.h>. They're ancient.
Use <iostream> instead.
Once that change is made, you also need to use the std namespace.
1
2
3
4
5
6
7
8
9
10
11
12
// Header Files
#include <iostream>
#include <ctime>
#include <string>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <cctype> 
#include <cmath>
using namespace std;

#include "cls.hpp" 
The only excuse for not doing this is if your compiler is so ancient that it won't work without the old <foo.h> headers.


don't #include source files

You'll notice above that I removed the "cls.cpp" from the #include directives, and replaced it with another file, "cls.hpp". That file looks like this:
1
2
3
4
5
6
7
#pragma once
#ifndef CLS_HPP
#define CLS_HPP

void CLS();

#endif 
That's it! Now when you compile, you must link the "cls.o" into your compilation. If you are using the GCC or any *nix CC, just add it to your compile command:

    g++ bj.cpp cls.cpp

If you are using something like VC++ or Borland C++ then add the "cls.cpp" file to your project from the "Project" menu. Then when you compile ("build") it should automatically link it for you.


main returns int

Line 76 should read int main().
Please just do it. You only have to type one character less.


users always press ENTER

Just to be clear, every time you ask your user to input something, he or she will always, always, always press ENTER when he or she is done.

The corollary is that you must always read that ENTER key (the newline, or '\n') immediately after every input.

Lines 83 to 84 have an example of that error in your program.
You asked cin to give you a number.
But you didn't ask cin to get rid of the ENTER key.

You tried to fix that error with lines 204 and 205, because that's where you perceived the problem to be happening. But the problem happened before you ever called loadprofiles().

Fix it with:
83
84
85
	cin >> option;
	cin.ignore( 80, '\n' );
	CLS(); 

Now your code in loadprofiles() can be fixed too:
201
202
203
204
205
206
                if (numprofiles == 0)                                           //If there are currently no profiles,
                {
                        cout << "No profiles were found, press enter to create a profile";
                        cin.ignore(80,'\n');
                        createprofile();
                }

I haven't gone entirely through your program, but I think most (if not all) the other flow control problems you have are related to this issue. (For example, when I create a profile, I get as many "profileN.dat" files as I let it create in my directory.)

Go through and make sure that every time you get something from the user, you also get rid of the newline.


character constants

On line 921 you used '/n' (multi-character constant) instead of '\n' (escape sequence for newline).


all your base are belong to us

You should give the user a way out. When the game starts, the user has the options of
  1. Play Game
  2. View High Scores
  3. Play in 2 player mode
Where is the option for, "I changed my mind and want to quit!"? You should always have an escape option. (Option three has inconsistent capitalization, BTW.)


main menu ui design

Just from a UI perspective, when you display the main menu, the first thing the runtitle() function should do is clear the screen.


fatal errors

If you start the game and select option two, "View High Scores", before ever playing the game, the program terminates with the message "Not Currently Available".

Termination is a pretty bad response to get after selecting something reasonable (after all, the choice was offered, and it is not unusual for games to come with preset high scores).

A better response would be to simply say, "There are no high scores yet. You must play the game first." After that, prompt the user to press ENTER (to redisplay the title menu), and continue on as if nothing horrible had happened.


screen width

As a final comment, you should be aware that some users don't always use an 80-column terminal display. I don't. (I had to open an 80-column terminal to run your program -- which is OK, as I have one handy, but that's not the point.)

There are several ways to handle this. The easiest would be just to tell your users that you require an 80-column display. However, the number one rule in UI design is "users don't read anything," so that is a sub-optimal solution.

The next easiest would be just to keep to 79 columns, and manually place a newline at the end of each line. This would look good on most terminals (as most terminals have at least eighty columns).

The nicest option is a lot more work: check the user's terminal size and adjust your output to fit. This is best, but it is also a lot more work, and you must also handle cases where the user has configured his or her terminal to be unusable... which is a pain.

I recommend the 79-column option.


edit -- non-standard functions == bad

Sorry, I forgot this one.
You use itoa() quite a few times in your code.
Don't do that.
It is non-standard. If you must, use sprintf() instead. Otherwise, stick to using the C++ streams, which do things like that for you automagically.
1
2
  int answer = 42;
  cout << "Hey, the answer was " << answer << ". So there. Nyah!\n";



Well, that's it for now. Hope this helps.
Last edited on
Topic archived. No new replies allowed.