Creating main menu for DOS program - c++

I'm writing a short text-adventure game and that game is ready, but now I want to do something with a main menu. Note that the whole game is in DOS.
This is what I want to achieve:
Create a main menu in the following way, but using while and switch loops. The switch loop will contain cases (case 1:, case 2:, case 3:, etc.) with the following options (which will cout above the loops)
cout << "[1] Play\n";
cout << "[2] Credits\n";
cout << "[3] Exit\n";
Now, the text-adventure game is too big to just put in this loop as it becomes increasingly hard to read because of nesting. There are loops in the game itself too, also while and switch loops. What I want to do now is something like the following, but I don't know how to do this. I will write it in psuedocode:
*open file game_name.cpp*
If player presses 1
Insert actual_game.cpp
Play game until over or user presses escape
else if player presses 2
Show credits
Return to main menu
else if player presses 3
Terminate the session
else
Shows the player that an invalid option has been chosen
The point is that I want to include multiple .cpp files instead of putting all the code in one single file (the actual_game.cpp). What is the best way to do this?

This question and answer is very similar to yours, take a look:
Link
Let me know if something is unclear in there. The bottom line is that you don't insert code files - those don't exist anyway after you compile your program. You call functions in response to each condition - those individual functions will, in turn, execute the relevant logic. You need to organize your game into a set of functions, where each function performs one particular job in the game (and likely call ever more specialized functions that handle the various locations in your game, etc.)
Here's an example:
// In GameFunctions.h:
bool StartGame ();
bool ShowCredits ();
bool ExitGame ();
// Add all function definitions here or create multiple header files to hold
// groups of function definitions. Include these headers files in your CPP files.
// In GameFunctions.cpp:
#include <iostream>
#include "GameFunctions.h"
using namespace std;
int main ( int argc, const char* argv[] )
{
int nKeyPress; // this holds the key pressed by the user
bool bContinue = true;
while ( bContinue )
{
... // read a key here into nKeyPress
switch ( nKeyPress )
{
case 1:
bContinue = StartGame ();
break;
case 2:
bContinue = ShowCredits ();
break;
case 3:
bContinue = ExitGame ();
break;
}
}
}
...
bool StartGame ()
{
// initialize your game here
InitGame ();
// Show the first room of your game and start waiting for
// user input (the user making various selections in the game).
// You'll invoke other rooms from this function as you respond to
// user selections.
ShowRoom ( 1 );
return ( true );
}
bool ShowCredits ()
{
... // show credits here
return ( true );
}
bool ExitGame ()
{
// do cleanup (if you have any to do) here
return ( false );
}
You can also break up your game code into multiple .cpp and .h files to group your functions into logical groups. Even if you don't use classes, having all your code in a single .cpp file is usually a bad idea, unless your game is very, very short. So you can create multiple .cpp files, for example, one for each room: each .cpp file will hold the code to handle a particular room in your game. You'll need the function definitions in a header file and you need to include all header files in a particular .cpp file that you intend to use. (You don't need to include every .h in every .cpp, though - you only need those headers that contain definitions that you intend to use in a single .cpp.)
At the end, your game will be made up of several .cpp and .h files and will have a number of functions: some will read user input, some will display messages on the screen, some may keep track of the user's score, some will initialize a room before the player first enters it, etc.
You'll likely need other header files from the standard C or C++ library, depending on what standard features you'll try to use.

For C++ compiler to use the function it need only to know the function's signature, not the whole function. After all .cpp files are compiled the linker must know about the whole functions, so that it can link all the parts into an application. Function's signature (also called "function declaration") is usually stored in header file (example.h), and the actual function (also called "function definition") is usually stored in source file (example.cpp). In one .cpp file you can call the function defined in another .cpp file, just add an include line where you tell the compiler where to look for that function's declaration (#include "example.h"):
-----------------
Main project file
-----------------
#include "actual_game.h"
#include "credits.h"
int main()
{
for (;;)
{
PrintMainMenu();
int choice = GetUsersChoice();
if (choice == CHOICE_PLAY_GAME)
PlayTheGame(); // This function is found in files actual_game.h and .cpp
else if (choice == CHOICE_SHOW_CREDITS)
ShowCredits(); // This function is found in files credits.h and .cpp
else if (choice == CHOICE_TERMINATE)
break;
else
ShowInvalidOptionMessage();
}
return 0;
}
------------------
File actual_game.h
------------------
void PlayTheGame();
--------------------
File actual_game.cpp
--------------------
#include "actual_game.h"
void PlayTheGame()
{
// The body of the function. If this function is very large and difficult to
// read by humans then divide it somehow to several other functions, that can
// be put in several files, and so easier to handle and maintain
}

Related

How i can implement a BackgroundWorker in C++ STL

Hello i'm newbie in C++ specially on STL,
I need to create a function with an infinite loop to calculate and process big data (such as Genetic Algorithm), but i also need keep Ui responsive and update it within (after each round) that infinite loop and start/stop operation manually.
something like this:
bool working = false;
void do_process()
{
while(working)
{
// do some stuff
}
}
void btnStart()
{
working = true;
do_process();
}
void btnEnd()
{
working = false;
}
would you please guide me to a proper solution without any 3rdparty lib, thanks.
and apologies for terrible English.
The code below should get you started. But be careful, implementing a multi-threading application is generally a hard problem also for experienced users. Lot of knowledge is required about memory access synchronization and deadlock analysis. Consider the example below is really essential. For instance, in btnStart and btnStop you should check if a thread is already running. Checking the global bool working may require synchronization. Similarly, checking for null pointer may require synchronization. Bottom line, it is way more complicate than it may seem.
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <memory>
bool working = false;
std::unique_ptr<std::thread> t;
void do_process()
{
while(working)
{
std::cout << "Hi. I am a secondary thread and I am running.\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void btnStart()
{
working = true;
t.reset(new std::thread(do_process)); // start the thread
}
void btnEnd()
{
working = false; // inform the thread of termination
t->join(); // wait for thread termination
t.reset(NULL);
}
int main()
{
std::cout << "Hi, I am the main thread.\n";
std::cout << "I'll now launch another thread and sleep for a while\n";
btnStart();
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
btnEnd();
std::cout << "What happened while I was slepping?\n";
return 0;
}
I am fairly new also to c++ but i have something that might help.
when i want to run something like an update to my code or to run something external without cramming my original project with code, i like to use ShellExecute to run another c++ program or external program. To use ShellExecute you need #include<windows.h>
For example if i want to update my program, i use #include<fstream>, #include<windows.h>, and #include<string> to check for a value in a file called 'updatereq.txt' (i make it my self). And in my program i run ifstream to check in the file if there is a '1'. If the if statement detects '1' it does this:
void Update(string filename)
{
ShellExecute(NULL,"open",filename.c_str(),NULL,NULL,SW_SHOWNORMAL)
}
This will run with:
HWND set as NULL, Operation set as: "open", File set as string:filenameconstant, Parameters set as NULL, Directory set as NULL(will run in the Directory of originally launching, usually at the main file), and Mode set as SW_SHOWNORMAL which will run it infront of you normally. This is also SW_SHOWMINIMIZED and SW_SHOWMAXIMIZED
Hope this helps!
PS: Remember to mention the file / program name that you are going to run when calling this function

RELEASE C++ Macro Definition

My company's main application uses OLE documents. Periodically, and unpredictably, the program closes its template documents improperly. So that at seemingly random times when they're opened, the OS throws STG_E_SHAREVIOLATION
I thought the problem might be the way we're closing the files when the user either exits the application or chooses File / Close from the menu. After a lot of debugging / tracing, it comes down to
/////////////////////////////////////////////////////////////////////////////
// 'Compound File' enabling in COleDocument
BOOL COleDocument::OnNewDocument()
{
// call base class, which destroys all items
if (!CDocument::OnNewDocument())
return FALSE;
// for file-based compound files, need to create temporary file
if (m_bCompoundFile && !m_bEmbedded)
{
// abort changes to the current docfile
RELEASE(m_lpRootStg);
// create new temporary docfile
LPSTORAGE lpStorage;
SCODE sc = ::StgCreateDocfile(NULL, STGM_DELETEONRELEASE|
STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
0, &lpStorage);
if (sc != S_OK)
return FALSE;
ASSERT(lpStorage != NULL);
m_lpRootStg = lpStorage;
}
return TRUE;
}
in OLEDOC1.CPP (part of the MFC libraries). Specifically the RELEASE(m_lpRootStg) macro line. Prior to executing this line, trying to move or delete the document results in the OS saying that the file is in use. After this line, the file is closed and able to be moved.
I'd like to subclass this method to experiment with alternative ways of closing the file. But, I cannot find the definition of the RELEASE macro anywhere. The closest I came was some code from IBM. Where is this macro defined? What is the definition?
It's in oleimpl2.h in the MFC src directory...
#ifndef _DEBUG
// generate smaller code in release build
#define RELEASE(lpUnk) _AfxRelease((LPUNKNOWN*)&lpUnk)
#else
// generate larger but typesafe code in debug build
#define RELEASE(lpUnk) do \
{ if ((lpUnk) != NULL) { (lpUnk)->Release(); (lpUnk) = NULL; } } while (0)
#endif

Send control back to main.cc file in my c++ project from another souce file

Is it possible to send control from other file to main file using GOTO statement if yes please tell. if is it not possible please tell me another method.
main.cc
{
outer: // label where I want to return
callingfunc()
//control go into calling func
}
source.cc //another source file with a class
class myclass
{
public:
callingfunc();
};
callingfunc()
{
some code
goto outer; //from here I want to send control to outer label in file **main.cc**
}
You can only goto labels in the same function, and it's very poor practice to break a function across source files (which is only possible if an #included file contains the first part of the function). To transfer execution, you normally want to use function calls (whether to a hardcoded function or one identified by e.g. a function pointer or std::function<>) and return statements, sometimes throw and exceptions, and very very rarely something unusual like setjmp/longjmp (if you need to ask this question you shouldn't be playing with those latter functions). You should explain more about your program - ideally post some code - if you want specific advice on what suits your needs.
Update: now you've posted some code, you could consider something like this...
// source.h
enum Flow { Outer, Continue }; // whatever names make sense to you...
Flow callingfunc();
// main.cc
#include "source.h"
if (callingfunc(...) == Outer) goto outer;
// source.cc
#include "source.h"
Flow callingfunc() { ...; return Outer; ... return Continue; }
It's best to try to find a better name than "Outer"... something that communicates the condition that callingfunc has found or the consequent processing it's recommending (e.g. Timeout, Can_Retry, Model_Unsolvable).

Implementing File class for both read and write operations on the file

I need to implement a class which holds a regular text file that will be valid for both read and write operations from multiple threads (say, "reader" threads and "writers").
I am working on visual studio 2010 and can use only the available libraries that it (VS 2010) has, so I chose to use the std::fstream class for the file operations and the CreateThread function & CRITICAL_SECTION object from the header.
I might start by saying that I seek, at the beginning, for a simple solution - just so it works....:)
My idea is as follows:
I created a File class that will hold the file and a "mutex" (CRITICAL_SECTION object) as private members.
In addition, this class (File class) provides a "public interface" to the "reader/writer" threads in order to perform a synchronized access to the file for both read and write operations.
See the header file of File class:
class File {
private:
std::fstream iofile;
int size;
CRITICAL_SECTION critical;
public:
File(std::string fileName = " ");
~File();
int getSize();
// the public interface:
void read();
void write(std::string str);
};
Also see the source file:
#include "File.h"
File :: File(std::string fileName)
{
// create & open file for read write and append
// and write the first line of the file
iofile.open(fileName, std::fstream::in | std::fstream::out | std::fstream::app); // **1)**
if(!iofile.is_open()) {
std::cout << "fileName: " << fileName << " failed to open! " << std::endl;
}
// initialize class member variables
this->size = 0;
InitializeCriticalSection(&critical);
}
File :: ~File()
{
DeleteCriticalSection(&critical);
iofile.close(); // **2)**
}
void File :: read()
{
// lock "mutex" and move the file pointer to beginning of file
EnterCriticalSection(&critical);
iofile.seekg(0, std::ios::beg);
// read it line by line
while (iofile)
{
std::string str;
getline(iofile, str);
std::cout << str << std::endl;
}
// unlock mutex
LeaveCriticalSection(&critical);
// move the file pointer back to the beginning of file
iofile.seekg(0, std::ios::beg); // **3)**
}
void File :: write(std::string str)
{
// lock "mutex"
EnterCriticalSection(&critical);
// move the file pointer to the end of file
// and write the string str into the end of the file
iofile.seekg(0, std::ios::end); // **4)**
iofile << str;
// unlock mutex
LeaveCriticalSection(&critical);
}
So my questions are (see the numbers regarding the questions within the code):
1) Do I need to specify anything else for the read and write operations I wish to perform ?
2) Anything else I need to add in the destrutor?
3) What do I need to add here in order that EVERY read operation will occur necessarily from the beginning of the file ?
4) What do I need to modify/add here in order that each write will take place at the end of the file (meaning I wish to append the str string into the end of the file)?
5) Any further comments will be great: another way to implement , pros & cons regarding my implementation, points to watch out , etc'.....
Thanks allot in advance,
Guy.
You must handle exceptions (and errors in general).
No, you destructor even has superfluous things like closing the underlying fstream, which the object takes care of itself in its destructor.
If you always want to start reading at the beginning of the file, just open it for reading and you automatically are at the beginning. Otherwise, you could seek to the beginning and start reading from there.
You already opened the file with ios::app, which causes every write operation to append to the end (including that it ignores seek operations that set the write position, IIRC).
There is a bunch that isn't going to work like you want it to...
Most importantly, you need to define what you need the class to behave like, i.e. what the public interface is. This includes guarantees about the content of the file on disk. For example, after creating an object without passing a filename, what should it write to? Should that really be a file who's name is a single space? Further, what if a thread wants to write two buffers that each contain 100 chars? The only chance to not get interrupted is to first create a buffer combining the data, otherwise it could get interrupted by a different thread. It gets even more complicate concerning the guarantees that your class should fulfill while reading.
Why are you not using references when passing strings? Your tutorial should mention them.
You are invoking the code to enter and leave the critical section at the beginning and end of a function scope. This operation should be bound to the ctor and dtor of a class, check out the RAII idiom in C++.
When you are using a mutex, you should document what it is supposed to protect. In this case, I guess it's the iofile, right? You are accessing it outside the mutex-protected boundaries though...
What is getSize() supposed to do? What would a negative size indicate? In case you want to signal errors with that, that's what exceptions are for! Also, after opening an existing, possibly non-empty file, the size is zero, which sounds weird to me.
read() doesn't return any data, what is it supposed to do?
Using a while-loop to read something always has to have the form "while try-to-read { use data}", yours has the form "while success { try-to-read; use data; }", i.e. it will use data after failing to read it.
Streams have a state, and that state is sticky. Once the failbit is set, it remains set until you explicitly call clear().
BTW: This looks like logging code or a file-backed message queue. Both can be created in a thread-friendly way, but in order to make suggestions, you would have to tell us what you are actually trying to do. This is also what you should put into a comment section on top of your class, so that any reader can understand the intention (and, more important now, so that YOU make up you mind what it's supposed to be).

add a single line of code in each function in visual studio

I would like to add a single line of code at the beginning of each function in my c++ visual studio 2010 project.
It would take months to manually add a line into each function. Are there any quick way or tool to solve this problem?
Edit: I would like to add a checkpoint for debugging purposes in every function in my project. I have a macro to handle adding checkpoints so the problem is now adding one single line of code. it could be anything, a macro, a console output, etc.
For example, have hundreds of functions:
void func1()
{
//code
}
int func2()
{
//code
}
char* func3()
{
//code
}
/* more functions */
bool func100()
{
//code
}
//I want them to become:
void func1()
{
myMacro;
//code
}
int func2()
{
myMacro;
//code
}
char* func3()
{
myMacro;
//code
}
/* more functions */
bool func100()
{
myMacro;
//code
}
You don't need to hack up your code to get function instrumentation! See here for example: http://www.drdobbs.com/automatic-code-instrumentation/184403601
The short story is that MSVC has _penter, a facility for doing pretty much what you're trying to accomplish here, but without modifying most of the source code.
As an aside, a standard term for what you asked about (adding code before function calls) is Aspect Oriented Programming.
MSVC supports keyboard macro recording (for c++ keyboard layout it is Ctrl+Shift+R - to start and Ctrl+Shift+P to stop). Define regular expression to find signature of function after that store keyboard macro something like following sequence:
F3 (for next function entry)
key down - to seek '{'
Ctrl + '}' to seek closing bracket
.... add extra line there ....
When keyboard-macro ready press Ctrl+R - to play this macro. The thousands of line handled very quickly