By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,763 Members | 1,609 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Zen and the Art of Debugging C/C++ in Linux with GDB

jwwicks
P: 19
C/C++ Programs and Debugging in Linux

This tutorial will give you a basic idea how to debug a program in Linux using GDB. As you are aware Visual Studio doesn’t run on Linux so you have to use some of the tools provided on the command-line. If you hate the command line tools, get over it since you’re bound to be using them at some point in your career. All commands in Linux ARE case sensitive so capital letters are different from lowercase letters. If you need basic information about a command type command --help at the shell prompt, where command is any Linux command and you’ll get a help screen. Here’s a basic list of commands you’ll get to know in Linux:

ls – Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Example: ls -l *.c

man – Usage: man [OPTION]... [COMMAND]...
Displays a manual page(s) about a command

clear – Clears the shell screen.

grep – Usage: grep [OPTION]... PATTERN [FILE] ...
Search for PATTERN in each FILE or standard input.
Example: grep -i 'hello world' menu.h main.c

apropos – Usage: apropos KEYWORD...
Search for KEYWORD in commands. Great for finding a command when you aren’t sure what it is.

Note: I had to change the makefile sections somewhat just so I could post so anytime you see GNU_COMPILER replace it with the appropriate command.

Creating a Project

In Linux you’ll use a shell of some sort, CShell or Bash etc… to create projects. For Windows based computers on a college campus you’ll probably use PuTTY. If you're already using Linux or some other variant of Unix then you'll have your own favorite Telnet/SSH Client. Once you start the PuTTY session you’ll get a screen similar to the following:



Your instructor/administrator will give you logon information. Once logged in, do a directory listing with the ls command. For most college accounts there is only one directory initially and that is public_html. In general it is a good practice to arrange your files on disk in some sort of directory scheme.
Note: When creating directories in Linux uppercase letters ARE significant; Projects is NOT the same as projects.
Create a directory called projects using the mkdir command like the following:



Change to the projects directory using the cd command. Create a directory for this application using the mkdir command again and call it MyProjectName1 where MyProjectName1 is some descriptive name for the program you are working on. For instance, if you are writing a program that computes income taxes type in MyTaxProgram or something similar.



Now change to this directory with the same cd command used previously. At this point your screen should look like the following:



Now that we have a project directory we’ll need to create a makefile to handle the building of our project once we get some source files created. The makefile is just a text file like any other but it has some special commands inside it to build our executable. To create a text file do the following:
1. Start you’re favorite Unix editor, there are several, vi and emacs are the most widely used editors but pico/nano is a good basic editor available on most machines in college labs. All the following examples use pico so the commands will be different if you are using a different editor. Type pico at the command prompt and you’ll see the following screen:



2. Press ctrl-O and save the file as makefile.



3. Then add the following text to the makefile:
Expand|Select|Wrap|Line Numbers
  1. main.exe: Source1.cpp
  2.         GNU_COMPILER -Wall Source1.cpp -o main.exe
  3.  
Note: The name Source1.cpp MUST match the name you'll use for the source code file in the next section.
4. Press ctrl-O again to save the changes to your makefile.


Creating a New Source Code File

If you are working on a new program, a new source code file must be created after the project directory has been created. The steps below describe how to create the new source code file:
1. Start you’re favorite Unix editor.
2. Press ctrl-O and save the file as Source1.cpp where Source1.cpp is some descriptive name for the program you are working on. For instance, if you are writing a program that computes income taxes type in MyTaxProgram.cpp or something similar.



3. Add the following text to your Source1.cpp file:
Expand|Select|Wrap|Line Numbers
  1. ////////////////////////// 
  2. /// source1.cpp - 
  3. /// Purpose: Some source code file 
  4. /// 
  5. /// Author: My Name 
  6. /// Date: January 1st, 2xxx 
  7. /// 
  8. //////////////////////// 
  9. /// History 
  10. /// INI 2xxx-01-01 v1.00.00 Initial release 
  11.  
  12. // Includes 
  13. #include <iostream> 
  14. #include <iomanip> 
  15. using namespace std; 
  16.  
  17. int main(int argc, char** argv) 
  18.     int ret_val = 0; // holds return value for main program 
  19.  
  20.     cout << "Hello World..." << endl; 
  21.  
  22.     return ret_val; 
  23.  
4. Press ctrl-O again to save the changes to your Source1.cpp file.


Compiling my first Program

Now that we have our makefile and Source1.cpp files created all that’s needed is to run the make utility to create our executable for testing.
1. Get a directory listing of the current files in our project directory by using the ls command.
2. Run the make command by typing make at the command prompt.
3. Messages from the compiler (error messages, warning messages and a successful compile/build message) will be displayed on screen.
4. Get a directory listing of the current files in our project directory by using the ls command again.


Note: Notice the new file created by make called main.exe. This is our executable.


Running a Program

Once the compile/build is successful, type the name of our executable at the command prompt to run it. In this case our executable is main.exe so type the following at the command prompt ./main.exe. The following output should be displayed:



Let’s add the following text to our code to make this program a little more interesting.
1. Add the following text before main:
Expand|Select|Wrap|Line Numbers
  1. // Global constants and variables 
  2. #define PRG_NAME "MyProjectName1 - v 1.0.00" 
  3. #define CPY_RGHT "Copyright © 2xxx - " 
  4. #define AUTHOR "My Name" 
  5.  
  6. // function prototypes 
  7. void show_copyright( void ); 
  8.  
2. Add this call to the copyright function before the “Hello World…” statement in main:
Expand|Select|Wrap|Line Numbers
  1. show_copyright(); 
  2.  
3. After main add the following function:
Expand|Select|Wrap|Line Numbers
  1. ///////////////////////// 
  2. /// show_copyright 
  3. /// Purpose: Show program name and copyright notice 
  4. /// 
  5. /// Parameters : None 
  6. /// Output : couts PRG_NAME, CPY_RGHT and AUTHOR defines 
  7. /// 
  8. /// Returns : None 
  9. /// SideEffects : None 
  10. //////////////////////// 
  11. void show_copyright ( void ) 
  12.     cout << AUTHOR << "'s " << PRG_NAME << endl; 
  13.     cout << CPY_RGHT << AUTHOR << endl << endl; 
  14.     return; 
  15.  
Your Source1.cpp file should look like the following when you are done with all these changes:



4. Now Compile/build and run the solution as you did before. You should see the following screen:




Debugging a Program

It can sometimes be difficult to determine why a program does not run successfully. A debugger allows a programmer to step through a program line-by-line to watch it execute and fail. The values of variables can be watched as execution takes place as well. GNU C++ has a debugger which can be used to step through a program. It is important to note that the program must compile first. Let’s add some more code to our Source1.cpp file (Note: this code has a logic problem in it to help you get used to debugging):

1. Add the following code before main after the show_copyright function prototype:
Expand|Select|Wrap|Line Numbers
  1. char get_choice( void ); 
  2. bool is_valid_choice( char ); 
  3.  
2. Add the following in main:
Expand|Select|Wrap|Line Numbers
  1. char choice; 
  2.  
3. Change the cout statement with “Hello World…” to the following:
Expand|Select|Wrap|Line Numbers
  1. do{ 
  2.     cout << "Hello World..." << endl; 
  3.     choice = get_choice(); 
  4. }while(!is_valid_choice( choice)); 
  5.  
4. Add the following functions after the show_copyright function:
Expand|Select|Wrap|Line Numbers
  1. ///////////////////////// 
  2. /// get_choice 
  3. /// Purpose: Check to see if user wants to continue 
  4. /// 
  5. /// Parameters: None 
  6. /// Output: Prompts user to continue program 
  7. /// 
  8. /// Returns: char ch - Choice entered by user 
  9. /// SideEffects: None 
  10. ///////////////////////// 
  11. char get_choice( void ) 
  12.     char ret_val; 
  13.     char ch; 
  14.     cout << "Do you want to continue (1 = Yes) (0 = No) ?: "; 
  15.     cin >> ch; 
  16.     ret_val = ch; 
  17.     return ret_val; 
  18.  
  19. ///////////////////////// 
  20. /// is_valid_choice 
  21. /// Purpose: Checks for valid yes or no entry to continue 
  22. /// 
  23. /// Parameters : char val - Current choice to continue 
  24. /// Output : Displays an error message if an invalid choice is passed 
  25. /// 
  26. /// Returns : true if choice is valid and false otherwise 
  27. /// SideEffects : None 
  28. //////////////////////// 
  29. bool is_valid_choice( char val ) 
  30.     bool ret_val = true; 
  31.     switch (val){ 
  32.     case 0: 
  33.     case 1: 
  34.         break; 
  35.     default: 
  36.         ret_val = false; 
  37.         cout << "Invalid choice : " << val << endl; 
  38.         cout << "Please enter one of the following(0 or 1) : " << endl; 
  39.         break; 
  40.     } 
  41.     return ret_val; 
  42.  
5. Build and run the solution as before and you should see the following screen:



6. Press 0 and instead of stopping the program like we asked, our program continues. We have a bug here Watson. Press Ctrl+C to stop executing the program. Now we’ll work on finding the bug in our code using the GNU debugger command gdb, but first we have to compile our program with some special code to enable debugging. To do that we’ll first need to create a directory named Debug and then modify our makefile to build our application with debugging information. At the command prompt use the mkdir command to create a new directory named Debug. Use the ls command to confirm that the directory was created and you should see a screen similar to the following:



Next open the makefile in your editor of choice, we’ll use pico again. Change the makefile so it has the following text in it:
Expand|Select|Wrap|Line Numbers
  1. main.exe: Source1.cpp
  2.         GNU_COMPILER -Wall Source1.cpp -o main.exe
  3.  
  4. dbg_main: Source1.cpp
  5.         GNU_COMPILER -g –Wall Source1.cpp –o ./Debug/main.exe
  6.  
Now run make using the following target make dbg_main and get a directory listing of the Debug directory using ls and you should have the following on your screen:



Now we’ll run the GNU debugger gdb with the newly compiled application with debugging information in it. Type gdb Debug/main.exe at the command prompt. You should see a screen similar to the following:



At this point you are in the debugger and there are a number of command that can be used from here to help you figure out what’s going on inside your program. Here’s a basic list of commands you’ll get to know in the GNU debugger:

help – Usage: help [COMMAND]
List information about the COMMAND
Example: help running or help breakpoints

list – Usage: list [LINE or FUNCTION][,][LINE]...
Lists the lines in a file, 10 lines at a time
Example: list 1,100

break – Usage: break [LINE or FUNCTION]
Creates a breakpoint at a specified LINE or FUNCTION location
Example: break 100

run – Usage: run [ARGUMENTS] ...
Runs the currently loaded program with the specified ARGUMENTS.
Example: run “-I” “hello world”

next – Usage: next
Steps through the next statement in the program.
step – Usage: step
Steps through one instruction only.

quit – Usage: quit
Quits the GNU debugger.


Breakpoints

A breakpoint tells the debugger to pause execution of a program until you tell it to continue. In order to step through a program (i.e. watch a program execute), a breakpoint should be set on the executable statement at which you want execution to pause. To set a breakpoint on a statement, use the break command at the (gdb) prompt. You specify either a function name or the line number of the executable to break on if you know it.
Determining where you want the breakpoint is a critical part of debugging. Put your breakpoint too soon in the execution of the program and you waste time stepping through code that doesn’t need to be debugged. Put the breakpoint too late and you might just miss the bug altogether. In our sample program above we have two possible places in our code that could be causing the problem. Either the get_choice function isn’t returning the proper value or the is_valid_choice function isn’t correctly checking the value. Let’s set a breakpoint to check the return value of the get_choice function. There are two possible places to check the value, one being inside the function itself or in the assignment statement in main. We’ll set our breakpoint in main so we can check the return value. First we’ll use the list command to find the line we want in the executable. In our example main starts at line 26 and ends at line 39 so the command list 26,39 will show those lines in the debugger:


Note: Your line numbers may vary depending on how you create the source file. Experiment.

In our example the line to set the breakpoint on is line number 35. So type in the command break 35 at the (gdb) prompt. You should see a screen similar to the following:




Watching a Program Execute

Once a breakpoint is set, start the debugger by using the run command. The program will begin to run but pause at the statement with the breakpoint prior to its execution. For our sample you should see something like the screen below:



At this point you have a number of choices (detailed below)
1) It is often helpful to know the value of a variable at a certain point in an executing program. The debugger allows you to look at the contents of variables as a program executes. Use the print command to display the value of an expression or variable.
2) If the current statement is a function call, Use the step command to go into the function to watch it execute.
3) Go to the next statement in the program by using the next command.

Let’s use the print command to inspect the value of choice in our application. Notice the value for choice in the window below is the char 0 or NULL. We’ll be double-checking it in the next section once the get_choice function returns a value.



Since we’re not interested in stepping into the get_choice function we’ll use the next command at the gdb prompt to execute the next statement in our program


Input and Output

As you may have notice output from our application appears in the gdb console window. You should get a prompt asking Do you want to continue (1 = Yes) (0 = No), type in a 0 and hit [Enter]. Now let’s use the print command again on choice. You should see a screen similar to the following:



Notice the change from before, 48 and ‘0’ instead of 0 and ‘\0’. The 48 is the ASCII value for the character 0, so the get_choice function is correctly returning a character value and choice is correctly storing that value. By stepping through the program we’ve discovered our bug isn’t in the get_choice function. Since our next statement in the program is the other function we need to check, is_valid_choice, and we know that a valid character is stored in choice and the is_valid_choice function should just keep looping with no error message. Use the step command to execute the is_valid_choice function. Notice what happens to our console window.



This isn’t correct since we know that the character 0 was passed in the variable choice to the function is_valid_choice by the following statement in main: }while(!is_valid_choice( choice));. So the problem has to be in the way in which is_valid_choice is checking the value. So we’ll use the step command to execute each statement in that function to find out where things are going wrong. But first you have to step past a couple of the statements to get to the is_valid_choice function again. Notice that the line number on the left hand side of the console window above is 34. That indicates the current statement. In our example it’s the cout statement that displays the “Hello World…” message. Type next to execute this statement. Type next to once again execute the get_choice function statement on line 35. In the console window type in 1 at the Do you want to continue prompt and then press [Enter] to continue the program. Now type step to debug the is_valid_choice function.



Notice that the line number on the left side of the screen is at line 90 inside the is_valid_choice function and that the variable called val has the value passed in the actual parameter choice, ASCII 49 and ‘1’, from main.

Lets list the next 10 lines by typing list 90,100 at the (gdb) prompt. Notice that line number 93 is the case statement for 1. Our program should execute line 93 since val has a ‘1’ in it. Type step twice more and notice that the line number jumps all the way to the first statement inside the default: section of the switch, line number 96. It should have hit the break statement in line 94 after seeing
Expand|Select|Wrap|Line Numbers
  1. case 1: 
  2.     break; 
  3.  
But it didn’t for some reason.


What You are Looking for

There are two ways in which a debugger is most helpful: 1) to verify statements are executed as expected, and 2) to verify that variables have their expected values. Look at the case statement very carefully we seem to be comparing an integer 1 with the character ‘1’, which is 49 in ASCII, so our program is functioning correctly but our logic test isn’t right. Change the case statement in the is_valid_choice function to look for character data:

Expand|Select|Wrap|Line Numbers
  1. switch (val){ 
  2.     case '0': 
  3.     case '1': 
  4.  
  5.         break;
  6.  
After editing the code to correct the problem, save your changes, rebuild the program with the command make dbg_main and then restart the debugger with gdb Debug/main.exe. Type break 35 to add the breakpoint again for the get_choice statement, then type run to begin the debugging session like before. Type next and then type a 1 again when prompted and press [Enter] as you did before in the console window. Type next again and notice that this time through, the application jumps to the end of the program, line number 38, like it should.



Type kill at the (gdb) prompt to stop debugging the application.
There is still one more logic problem in this program and you should use the same techniques to find it. (Hint: the program should continue printing “Hello World… and asking the user to continue if the user enters a 1 at the prompt.)


Solutions

Here's a strictly Standard C solution...
Expand|Select|Wrap|Line Numbers
  1. ///////////////////////////////////////
  2. /// \file main.c
  3. /// \brief Some source code file Project Main Module
  4. /// 
  5. /// \author My Name
  6. /// \version 00.99.00
  7. /// \date January 1st, 2xxx
  8. ///
  9. //////////////////////// 
  10. // History 
  11. // INI 2xxx-01-01 v1.00.00 Initial release 
  12.  
  13. // Includes 
  14. #include <stdio.h> 
  15. #include <stdlib.h>
  16.  
  17. // Global constants and variables 
  18. #define PRG_NAME "MyProjectName1 - v 1.0.00" 
  19. #define CPY_RGHT "Copyright © 2xxx - " 
  20. #define AUTHOR "My Name" 
  21.  
  22. // function prototypes 
  23. void show_copyright( void ); 
  24. char get_choice( void ); 
  25. unsigned int is_valid_choice( char ); 
  26.  
  27. // Uncomment to run just the testing main
  28. //#define TEST 1
  29.  
  30. /////////////////////////
  31. /// \fn main(int argc, char** argv)
  32. /// \brief Main module for Hello World program.
  33. ///
  34. /// \param argc - integer number of arguments passed from system to program
  35. /// \param argv - pointer to array of characters of arguments passed to program from system
  36. ///
  37. /// \return integer value for success or failure
  38. /////////////////////////
  39. #ifndef TEST
  40. int main(int argc, char** argv) 
  41.     int ret_val = 0; // holds return value for main program 
  42.     char choice = '0';
  43.     show_copyright();
  44.  
  45.     do{    
  46.         do{ 
  47.             printf("Hello World...\n"); 
  48.             choice = get_choice(); 
  49.         }while(!is_valid_choice( choice));
  50.     }while(choice == '1');
  51.  
  52.     return ret_val; 
  53. #else // Testing Main
  54. int main( int argc, char** argv)
  55. {
  56.     int ret_val = 0;
  57.  
  58.     return ret_val;    
  59. }
  60. #endif
  61.  
  62. ///////////////////////// 
  63. /// \fn show_copyright(void) 
  64. /// \brief Show program name and copyright notice 
  65. /// 
  66. /// \b SideEffects : None\n
  67. /// \b Output : couts PRG_NAME, CPY_RGHT and AUTHOR defines\n
  68. ///
  69. /// \return None
  70. //////////////////////// 
  71. void show_copyright ( void ) 
  72.     printf("%s 's %s\n", AUTHOR, PRG_NAME); 
  73.     printf("%s %s\n", CPY_RGHT, AUTHOR); 
  74.     return; 
  75.  
  76. ///////////////////////// 
  77. /// \fn get_choice( void )
  78. /// \brief Check to see if user wants to continue 
  79. /// 
  80. /// \b SideEffects: None\n 
  81. /// \b Output: Prompts user to continue program\n
  82. /// 
  83. /// \param None 
  84. /// 
  85. /// \return char ch - Choice entered by user 
  86. ///////////////////////// 
  87. char get_choice( void ) 
  88.     char ret_val; 
  89.     char ch; 
  90.     printf("Do you want to continue (1 = Yes) (0 = No) ?: ");
  91.     fflush(stdin);
  92.     scanf("%c^%*",&ch); 
  93.     ret_val = ch;     
  94.     return ret_val; 
  95.  
  96. ///////////////////////// 
  97. /// \fn is_valid_choice( char val ) 
  98. /// \brief Checks for valid yes or no entry to continue 
  99. /// 
  100. /// \b SideEffects : None\n 
  101. /// \b Output : Displays an error message if an invalid choice is passed \n
  102. /// 
  103. /// \param val - Current choice to continue 
  104. /// 
  105. /// \return boolean true if choice is valid and false otherwise 
  106. //////////////////////// 
  107. unsigned int is_valid_choice( char val ) 
  108.     unsigned int ret_val = 1; 
  109.     switch (val){ 
  110.         case '0': 
  111.         case '1': 
  112.             break; 
  113.         default: 
  114.             ret_val = 0; 
  115.             printf("Invalid choice : %c\n", val); 
  116.             printf("Please enter one of the following(0 or 1) : \n"); 
  117.             break; 
  118.     } 
  119.     return ret_val; 
  120.  
A C++ with Streams solution
Expand|Select|Wrap|Line Numbers
  1. ///////////////////////////////////////
  2. /// \file main.cpp
  3. /// \brief Some source code file Project Main Module
  4. /// 
  5. /// \author My Name
  6. /// \version 00.99.00
  7. /// \date January 1st, 2xxx
  8. ///
  9. //////////////////////// 
  10. // History 
  11. // INI 2xxx-01-01 v1.00.00 Initial release 
  12.  
  13. // Includes 
  14. #include <iostream> 
  15. #include <iomanip> 
  16. using namespace std; 
  17.  
  18. // Global constants and variables 
  19. const char PRG_NAME[] = {"MyProjectName1 - v 1.0.00"};
  20. const char CPY_RGHT[] = {"Copyright © 2xxx - "};
  21. const char AUTHOR[] = {"My Name"}; 
  22.  
  23. // function prototypes 
  24. void show_copyright( void ); 
  25. char get_choice( void ); 
  26. bool is_valid_choice( char ); 
  27.  
  28. // Uncomment to run just the testing main
  29. //#define TEST 1
  30.  
  31. /////////////////////////
  32. /// \fn main(int argc, char** argv)
  33. /// \brief Main module for Hello World program.
  34. ///
  35. /// \param argc - integer number of arguments passed from system to program
  36. /// \param argv - pointer to array of characters of arguments passed to program from system
  37. ///
  38. /// \return integer value for success or failure
  39. /////////////////////////
  40. #ifndef TEST
  41. int main(int argc, char** argv) 
  42.     int ret_val = 0; // holds return value for main program 
  43.     char choice;
  44.     show_copyright();
  45.  
  46.     do{
  47.         do{ 
  48.             cout << "Hello World..." << endl; 
  49.             choice = get_choice(); 
  50.         }while(!is_valid_choice( choice)); 
  51.     }while(choice == '1');
  52.  
  53.     return ret_val; 
  54. #else // Testing Main
  55. int main( int argc, char** argv)
  56. {
  57.     int ret_val = 0;
  58.  
  59.     return ret_val;    
  60. }
  61. #endif
  62.  
  63. ///////////////////////// 
  64. /// \fn show_copyright(void) 
  65. /// \brief Show program name and copyright notice 
  66. /// 
  67. /// \b SideEffects : None\n
  68. /// \b Output : couts PRG_NAME, CPY_RGHT and AUTHOR defines\n
  69. ///
  70. /// \return None
  71. //////////////////////// 
  72. void show_copyright ( void ) 
  73.     cout << AUTHOR << "'s " << PRG_NAME << endl; 
  74.     cout << CPY_RGHT << AUTHOR << endl << endl; 
  75.     return; 
  76.  
  77. ///////////////////////// 
  78. /// \fn get_choice( void )
  79. /// \brief Check to see if user wants to continue 
  80. /// 
  81. /// \b SideEffects: None\n 
  82. /// \b Output: Prompts user to continue program\n
  83. /// 
  84. /// \param None 
  85. /// 
  86. /// \return char ch - Choice entered by user 
  87. ///////////////////////// 
  88. char get_choice( void ) 
  89.     char ret_val; 
  90.     char ch; 
  91.     cout << "Do you want to continue (1 = Yes) (0 = No) ?: "; 
  92.     cin >> ch; 
  93.     ret_val = ch;     
  94.     return ret_val; 
  95.  
  96. ///////////////////////// 
  97. /// \fn is_valid_choice( char val ) 
  98. /// \brief Checks for valid yes or no entry to continue 
  99. /// 
  100. /// \b SideEffects : None\n 
  101. /// \b Output : Displays an error message if an invalid choice is passed \n
  102. /// 
  103. /// \param val - Current choice to continue 
  104. /// 
  105. /// \return boolean true if choice is valid and false otherwise 
  106. //////////////////////// 
  107. bool is_valid_choice( char val ) 
  108.     bool ret_val = true; 
  109.     switch (val){ 
  110.         case '0': 
  111.         case '1': 
  112.             break; 
  113.         default: 
  114.             ret_val = false; 
  115.             cout << "Invalid choice : " << val << endl; 
  116.             cout << "Please enter one of the following(0 or 1) : " << endl; 
  117.             break; 
  118.     } 
  119.     return ret_val; 
  120.  
And finally a C++ with classes solution

main.cpp
Expand|Select|Wrap|Line Numbers
  1. ///////////////////////////////////////
  2. /// \file main.cpp
  3. /// \brief Some source code file Project Main Module
  4. /// 
  5. /// \author My Name
  6. /// \version 00.99.00
  7. /// \date January 1st, 2xxx
  8. ///
  9. //////////////////////// 
  10. // History 
  11. // INI 2xxx-01-01 v1.00.00 Initial release 
  12.  
  13. // Includes 
  14. #include <iostream> 
  15. #include <iomanip>
  16. #include "oApp.h"
  17.  
  18. using namespace std; 
  19.  
  20. // Uncomment to run just the testing main
  21. //#define TEST 1
  22.  
  23. /////////////////////////
  24. /// \fn main(int argc, char** argv)
  25. /// \brief Main module for Hello World program.
  26. ///
  27. /// \param argc - integer number of arguments passed from system to program
  28. /// \param argv - pointer to array of characters of arguments passed to program from system
  29. ///
  30. /// \return integer value for success or failure
  31. /////////////////////////
  32. #ifndef TEST
  33. int main(int argc, char** argv) 
  34.     int ret_val = 0; // holds return value for main program 
  35.     oApp* myApp = new oApp;
  36.  
  37.     myApp->init("Your Message Here...\n");
  38.     myApp->set_copyright("Copyright© 2006-2008 - ");
  39.     myApp->set_author("Your Name");
  40.     myApp->set_program_name("YourProgramName v00.99.00");
  41.     myApp->run();
  42.     myApp->done();
  43.  
  44.     delete myApp;
  45.  
  46.     return ret_val; 
  47. #else // Testing Main
  48. int main( int argc, char** argv)
  49. {
  50.     int ret_val = 0;
  51.  
  52.     return ret_val;    
  53. }
  54. #endif
  55.  
oApp.h
Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <string>
  4. using namespace std;
  5.  
  6. class oApp{
  7.  
  8. public:
  9.     oApp(){
  10.         m_choice = '0';
  11.         m_author = "My Name";
  12.         m_copyright = "Copyright © 2xxx - ";
  13.         m_program = "MyProjectName1 v1.0.00";
  14.         m_message = "Hello World...";
  15.     }
  16.  
  17.     ~oApp() {};
  18.     void init( const string s );
  19.     void run( void );
  20.     void done( void );
  21.  
  22.     string get_copyright( void );
  23.     bool set_copyright( const string copyright );
  24.     string get_author( void );
  25.     bool set_author( const string author );
  26.     string get_program_name( void );
  27.     bool set_program_name( const string name );
  28.  
  29.     void show_copyright( void );
  30.  
  31. private:
  32.     string m_author;
  33.     string m_program;
  34.     string m_copyright;
  35.     string m_message;
  36.     char m_choice;
  37.  
  38.     char get_choice( void );
  39.     bool is_valid_choice( char val );
  40. };
  41.  
oApp.cpp
Expand|Select|Wrap|Line Numbers
  1. #include "oApp.h"
  2.  
  3. void oApp::init( const string s )
  4. {
  5.     this->m_message = s;
  6. }
  7.  
  8. void oApp::run( void )
  9. {
  10.     show_copyright();
  11.  
  12.     do{
  13.         do{ 
  14.             cout << this->m_message << endl; 
  15.             this->m_choice = get_choice(); 
  16.         }while(!is_valid_choice( this->m_choice )); 
  17.     }while(this->m_choice == '1');
  18. }
  19.  
  20. void oApp::done( void ){}
  21.  
  22. string oApp::get_copyright( void )
  23. {
  24.     string ret_val = this->m_copyright;
  25.     return ret_val;
  26. }
  27.  
  28. bool oApp::set_copyright( const string copyright )
  29. {
  30.     bool ret_val = false;
  31.     m_copyright = copyright;
  32.     ret_val = this->m_copyright == copyright;
  33.     return ret_val;
  34. }
  35.  
  36. string oApp::get_author( void )
  37. {
  38.     string ret_val = this->m_author;
  39.     return ret_val;
  40. }
  41.  
  42. bool oApp::set_author( const string author )
  43. {
  44.     bool ret_val = false;
  45.     m_author = author;
  46.     ret_val = this->m_author == author;
  47.     return ret_val;
  48. }
  49.  
  50. string oApp::get_program_name( void )
  51. {
  52.     string ret_val = this->m_program;
  53.     return ret_val;
  54. }
  55.  
  56. bool oApp::set_program_name( const string name )
  57. {
  58.     bool ret_val = false;
  59.     m_program = name;
  60.     ret_val = this->m_program == name;
  61.     return ret_val;
  62. }
  63.  
  64. ///////////////////////// 
  65. /// \fn get_choice( void )
  66. /// \brief Check to see if user wants to continue 
  67. /// 
  68. /// \b SideEffects: None\n 
  69. /// \b Output: Prompts user to continue program\n
  70. /// 
  71. /// \param None 
  72. /// 
  73. /// \return char ch - Choice entered by user 
  74. ///////////////////////// 
  75. char oApp::get_choice( void )
  76. {
  77.     char ret_val; 
  78.     char ch; 
  79.     cout << "Do you want to continue (1 = Yes) (0 = No) ?: "; 
  80.     cin >> ch; 
  81.     ret_val = ch;     
  82.     return ret_val; 
  83. }
  84.  
  85. ///////////////////////// 
  86. /// \fn is_valid_choice( char val ) 
  87. /// \brief Checks for valid yes or no entry to continue 
  88. /// 
  89. /// \b SideEffects : None\n 
  90. /// \b Output : Displays an error message if an invalid choice is passed \n
  91. /// 
  92. /// \param val - Current choice to continue 
  93. /// 
  94. /// \return boolean true if choice is valid and false otherwise 
  95. //////////////////////// 
  96. bool oApp::is_valid_choice( char val )
  97. {
  98.     bool ret_val = true; 
  99.     switch (val){ 
  100.         case '0': 
  101.         case '1': 
  102.             break; 
  103.         default: 
  104.             ret_val = false; 
  105.             cout << "Invalid choice : " << val << endl; 
  106.             cout << "Please enter one of the following(0 or 1) : " << endl; 
  107.             break; 
  108.     } 
  109.     return ret_val; 
  110. }
  111.  
  112. ///////////////////////// 
  113. /// \fn show_copyright(void) 
  114. /// \brief Show program name and copyright notice 
  115. /// 
  116. /// \b SideEffects : None\n
  117. /// \b Output : couts m_ProgramName, m_Copyright and m_Author\n
  118. ///
  119. /// \return None
  120. //////////////////////// 
  121. void oApp::show_copyright ( void ) 
  122.     cout << this->m_author << "'s " << this->m_program << endl; 
  123.     cout << this->m_copyright << this->m_author << endl << endl; 
  124.     return; 
  125.  
Aug 7 '08 #1
Share this Article
Share on Google+
2 Comments


P: 1
Excellent! Love the multiple solution approach you took! Superb.
Aug 30 '08 #2

P: 1
Hello,

"[...] As you are aware Visual Studio doesn’t run on Linux [...]"

but you can connect from Visual Studio to Linux host (for example through ssh) ;) so if you are interested in debugging Linux applications under Visual Studio then please visit our site: http://www.wingdb.com :)

Kind Regards,
WinGDB team
Jul 1 '09 #3