F . A . Q .

INTRODUCTION
I received a lot of questions after my page was listed on good Gustavo's C/C++ site. And instead of drowning in the same questions I thought I could add this resource to the page. Everytime I answer a question (unless the question is odd like, "Are you gay?" and "Why does your page suck?") I'll post the question and answer here. And because I'm vain I also made a comments page to keep my spirit up. This page is only linked from here to prevent clutter. Also, I don't usually change the content of the original questions, I simply cut and paste them; so don't blame me for mispellings and such . Now without further ado, I present my Frequently Asked Questions!

TABLE OF CONTENTS

QUESTIONS: Multi-Dimensional Arrays
I actually received two or three questions about multi-dimensional arrays of late (12 NOV 1998) and I'm going to add that to my Advanced Arrays page so look for more answers there.

Q: How can I input values into an array from the keyboard ?example:
cout<<"Enter the scores for bowler1 "123234345
cin >> ?
This is a 4x6 array.(5 man bowling team) I would like to enter the scores on the same line.

A: You'd have to reference each array index seperately. Say if you made an array like:

char arr[5][50];

That would make an array that is basically 5 lines at 50 characters a line. And to get input for all 5 lines we'd have to do each one seperately:

cout << "Enter line1:";
cin >> arr[0];
cout << "Enter line2:";
cin >> arr[1];


QUESTIONS: Redefinition Errors
Q: Dear Sir,

I would like a small clarification from you.I tried to compile the following code:

int fn(int a){ return 1;}
int fn(const int a){ return 2;}
void main()
{
}

It gave me a redefinition error at compile time.Could you please clarify why?

A:The compiler does not know which function you called 'fn' to use as the definition for that name. Even though one takes a constant (const int a) and one takes a variable (int a) it still sees both as taking a single integer, constant or no constant. You're going to have to name one something different. Like 'fn1' and 'fn2'. Or rather just make one of those functions than the other because they'll both do the same thing only in one you can't change the parameter 'a'.

QUESTIONS: Conversion Between Arrays
Q: How would one go about copying an char array to an int array? And back again?
A:It'd basically be the same as copying a char array into another char array. As long as both arrays are the same length you'd do something like the following to copy a char array into an int array:
for (i = 0; i < length_of_arrays; i++)
{
  int_array[i] = (int)char_array[i];
}
And then this to copy an int array into a char array:
for (i = 0; i < length_of_arrays; i++)
{
  char_array[i] = (char)int_array[i];
}
The (int) tells the subscript of the character array to act like an integer. The (char) tells the subscript of the integer array to act like a char, etc. etc.

QUESTION: What Is A Default Constructor
Q: What is a default constructor?

A:: A constructor that doesn't take any parameters. The following class only has one constructor, it doesn't take parameters, and therefore is a default constructor.

class date
{
  public:
    date()
    {
      cout << "This is a DEFAULT constructor" << endl;
    }
};
The term default is used because when an object is created without passing any parameters to the constructor, the default is used.

QUESTIONS: Command Line Parameters
Q: I have looked through every tutorial i can find, but i havn't found the answer to my question. i want to know how to get command line options in a c program. if you don't know what command line options are, then don't bother to reply. an example would be:
the program add's 2 numbers
c:\> adder 93 25
and then the program would take 93 and add it to 25.

A: To make your program accept command line parameters you will have to give your 'main()' function two parameters. The first an 'int' which people generally call 'argc', the second an array of character pointers (to strings) usually dubbed 'argv'. It looks like this:

int main(int argc, char *argv[])

'argc' will store the number of command line parameters your program was passed plus 1. So if your program is called "foo" and you type "foo par1 par2" at the prompt then 'argc' will be 3. The reason being, it counts the program name as a parameter.

The first subscript (zero) of argv[] will store the full file name and path of the program. If you ran your program from "C:\PROGS\" then argv[0] would store (or point to actually) "C:\PROGS\FOO.EXE". The subscripts following contain the parameters. So argv[1] would be "par1" and argv[2] would be "par2". Here's a nifty program you can try out:
//-------------------------------------------------------------------
#include <iostream.h>

int main(int argc, char *argv[])
{
  int i;

  cout << "Running " << argv[0] << endl;
  for (i = 1; i < argc; i++)
  {
    cout << "  Argument #" << i << " is \"" << argv[i] << "\"."
         << endl;
  }

  return 0;
}
//-------------------------------------------------------------------

QUESTIONS: Files on Objects
Q: do you have any hints for writing classes to a file? A: To write out a class to a file what you actually have to do is write out each of its data members to the file and then when you read them back in later you put them into the object's variables. I usually make two functions in my class, load and save. Both of them take one argument, a filestream. That way you can already have a filestream open and just read it into the object or multiple objects. Kind of like this (btw, I don't know if this runs I didn't test it, you may have to diddle with a couple things :):
// -------------------------------------------------------------
class Something
{
  public:
    int Load (fstream &file);
    int Save (fstream &file);

    short x, y;
};

int Something::Load(fstream &file)
{
  file.read(&x, 2);
  file.read(&y, 2);
  return 0;
}

int Something::Save(fstream &file)
{
  file.write(&x, 2);
  file.write(&y, 2);
  return 0;
}

// ----------------------------------------------------------------
fstream f;
Something o1, o2;

cout << "Initializing ... " << endl;

o1.x = 0;
o1.y = -5;
o2.x = 182;
o2.y = 67;
cout << "Values are: O1[" << o1.x << ", " << o1.y << "] O2["
     << o2.x << ", " << o2.y << "]." << endl;

cout << "Saving to file ... " << endl;

f.open("data.dat", ios::out | ios::binary);
o1.Save(f);
o2.Save(f);
f.close();

o1.x = 0;
o1.y = 0;
o2.x = 0;
o2.y = 0;

cout << "Values are: O1[" << o1.x << ", " << o1.y << "] O2["
     << o2.x << ", " << o2.y << "]." << endl;

cout << "Loading from file ... " << endl;

f.open("data.dat", ios::in | ios::binary);
o1.Load(f);
o2.Load(f);
f.close();

cout << "Values are: O1[" << o1.x << ", " << o1.y << "] O2["
     << o2.x << ", " << o2.y << "]." << endl;

// ----------------------------------------------------------------
Make any sense? I hope so. Just remember that you actually have to write out the individual variables to the file.

QUESTIONS: Files on Objects
Q: Where can I get a code in C that let's me access the dos shell?

A: To call DOS commands from inside your program you use the "system()" function. To use this function you must include "stdlib.h". And lastly to access the DOS shell you'd do the following:
system("command");
So, you might have a program like the following:
// ------------------------------------------------------------------

#include <iostream.h>
#include <stdlib.h>

int main()
{
  cout << "Calling dos shell (type Exit to return) ... " << endl;
  system("command");
  cout << "Welcome back to my program!" << endl;
  return 0;
}

// ------------------------------------------------------------------

QUESTIONS: Graphics in C++
Q: how do I add graphics to my C++ program?

A: This is a complex and time consuming process, to say the least. If you're going to get into this I suggest you use a graphics engine that someone else has done and/or is working on. Look under "Multimedia" on my links page. I highly recommend you take a look at Allegro.

QUESTIONS: Arrays of Structures
Q: Could you please explain passing arrays of structs to functions

A: TO PROTOTYPE: The name of the struct followed by the name of the parameter followed by [].

TO PASS: The name of the variable.

So:
// structure definition
struct
{
  char str[20];
} egg;

// function prototype
  void func (egg x[]);
//           ^   ^ ^
//           |   | |
//name of struct | |
//name of parameter|
//         to show we're passing an array

main()
{
  // create an array of objects of type 'egg'
  egg var[20];

  // pass the array we made to the function
  func (var);
}

// function definition
void func (egg x[])
{

}

QUESTIONS: Pointers/Arrays
Q: I'm trying to understand pointers/arrays -- going to be bald soon if I don't get it figured out.

A: The low-down? First what's a pointer? A pointer is a variable that stores a memory address. So its kind of like an entry in your address book. It stores the ADDRESS of your momma's house, but its not actually your momma's house. ;) They call them pointers because they POINT to memory addresses. Like if you were a variable and I were a pointer, I would point to you but I wouldn't actually be you.

Now what really IS an array? An array is actually a POINTER. It points to an empty spot in memory. The size of that emptiness is determined by you when you declare it. So if we declared an array like this:
char myarray[20];
That would point to an empty spot in memory followed by nineteen more empty spots. To delve into this further, let's say that memory location was "102 99th St. Oak" (just to be funny cuz computers' addresses are in hex). And that location is empty, followed by nineteen more empty spaces:
myarray    ->    102 99th St. Oak (subscript  0: myarray[0])
                 103 99th St. Oak (subscript  1: myarray[1])
                 104 99th St. Oak (subscript  2: myarray[2])
                 105 99th St. Oak (subscript  3: myarray[3])
                 106 99th St. Oak (subscript  4: myarray[4])
                 107 99th St. Oak (subscript  5: myarray[5])
                 108 99th St. Oak (subscript  6: myarray[6])
                 109 99th St. Oak (subscript  7: myarray[7])
                 110 99th St. Oak (subscript  8: myarray[8])
                 111 99th St. Oak (subscript  9: myarray[9])
                 112 99th St. Oak (subscript 10: myarray[10])
                 113 99th St. Oak (subscript 11: myarray[11])
                 114 99th St. Oak (subscript 12: myarray[12])
                 115 99th St. Oak (subscript 13: myarray[13])
                 116 99th St. Oak (subscript 14: myarray[14])
                 117 99th St. Oak (subscript 15: myarray[15])
                 118 99th St. Oak (subscript 16: myarray[16])
                 119 99th St. Oak (subscript 17: myarray[17])
                 120 99th St. Oak (subscript 18: myarray[18])
                 121 99th St. Oak (subscript 19: myarray[19])
That last one (121 99th St. Oak) we'd use for our NULL character. Now if we were crazy and weird we could add one to 'myarray' like this:
myarray++;
Now it would point to 103 99th St. Oak. That means we'd only have like 19 empty areas to work with, plus we need to use one for the NULL character.

// -----------------------------------------------------------------
#include <iostream.h>

main()
{
  // I save the last character for a NULL character (myarray[19] = 0)
  char myarray[20] = "1234567890abcdefghi";

  // create a pointer
  char *ptr;

  // 'myarray' points to an address that has 19 subsequent empty slots
  // we know that by how we declared it above.  When I do the follow-
  // ing, I give 'ptr' the same memory address.  So know it too will
  // point to that same spot in memory.  Now we can mess with THAT
  // and not change where our original 'myarray' points to.  That way
  // if we really mess it up we can always "ptr = myarray" to get the
  // address back
  ptr = myarray;

  cout << "myarray = \"" << myarray << "\"" << endl;
  cout << "ptr = \"" << ptr << "\"" << endl;

  // now we're going to do something strange that you might find
  // interesting.  We're going to add one to the value of 'ptr'
  // and then print subscript 0 of 'ptr'.  That means whatever 
  // character that its pointing to will be printed.
  cout << "ptr[0] = '" << ptr[0] << "'" << endl;
  ptr++;
  cout << "ptr[0] = '" << ptr[0] << "'" << endl;

  // pretty cool, huh?  Now we'll keep doing this until we reach
  // a NULL character.  But first let's start over.
  ptr = myarray;

  cout << "ptr ... ";

  while (ptr[0] != 0) // loop while we're NOT equal to a NULL char
  {
    cout << ptr[0];
    ptr++;
  }

  cout << " ... " << endl;

  // okay that's it... hope it was useful at all :)
}

// -----------------------------------------------------------------

QUESTIONS: Exits Immediately After Execution
Q: Here's question that's "KILLIN" me. I've got Boreland C++ and when I write up a program and run the debugger, if it runs OK it quickly pops up and then goes away, so I can't tell what the hell my results were...it's KILLIN me!!! Is there something I can add to the program or something to adjust in the program to stop and show me the results?

A: That always pissed me off when (back in the days) I was using "Turbo C++" in my old Community College "C Programming" course. You'd think they'd add something like they have in Visual C++ and the Borland IDE where it adds a "press any key to continue" at the bottom. But you can do that yourself too. At the bottom of your program (in function main()), add something like I have here:
main()
{

  // this being the end of your program of course ...
  { char p; // a temporary variable
    cout << "press enter to continue";
    cin.get(p);
  }
}

QUESTIONS: Screen Clearing (CLS)
Q: I need some help in finding a clear screen command. I need a command which can clear the output screen such as the cls command in basic.

A: There is no standard way that I know of to clear the screen. You can print a bunch of blank lines, like:
// -[cls method 1]----------------------------------------------------------
int i;
for (i = 0; i < 24; i++)
  cout << endl;
// -------------------------------------------------------------------------
Another way is if you're using DOS or a system that accepts the CLS command at the prompt (I believe LINUX does as well), then you can call the system:
// -[cls method 2]----------------------------------------------------------
system("cls");
// -------------------------------------------------------------------------
For this last one to work you'd have to include "stdlib.h". In Borland C++ and other compilers there is a function called 'clrscr()' in "conio.h" that you can use just like a CLS:
// -[cls method 3 - not portable!]------------------------------------------
clrscr();
// -------------------------------------------------------------------------
Compilers create a macro named something similar to their own name when you include any one of their libraries. This makes it easy to detect the compiler you're using. This is useful for things making a function that will compile flawlessly in any compiler. Below is what I mean. Cut out the following code and put it at the top of ANY of your programs and you will be able to call "cls();" to clear the screen:
// -[cut here]--------------------------------------------------------------
#if defined(BORLAND_C)
  #include <conio.h>
  #define cls() clrscr()
#endif

#if !defined(BORLAND_C)
  #include <stdlib.h>
  #define cls() system("cls");
#endif
// -[end cut here]----------------------------------------------------------

QUESTIONS: Checking User Input
Q: I'm writing a program. and I finally figured out that you had to have your variables as 'char' in order to do the isdigit, isalpha checks on them. But I'm dealing with math equations. so I will have to convert them. But I want to check and make sure user doesn't enter a character or something invalid. thats why I put the isdigit check. so what should I do?

A: You must get user input into a string variable. Check the string variable for errors and then, if it is correct, convert it into an integer with atoi() or some similar function. Take a look at the following:

// -[checking user input]---------------------------------------------------

#include <iostream.h> // for cout/cin
#include <stdlib.h>   // for atoi()
#include <ctype.h>    // for isdigit()

main()
{
  char usrinp[80];    // string to store user input
  int value;          // the variable we'll want to store the end value in
  int i;              // simple index variable

  do
  {
    value = 0;
    cout << "Please enter a whole number (not zero!): ";
    cin >> usrinp;

    for (i = 0; usrinp[i]; i++)
    {
      if (!isdigit(usrinp[i])) break;
    }
    
    if (usrinp[i])
      cout << "I said a NUMBER numb-skull!!!" << endl;
    else
      value = atoi(usrinp);
  } while (!value);

  cout << "The value is " << value << endl;
}

// -------------------------------------------------------------------------

QUESTIONS: Random Numbers
Q: I need to know how to use the random function

A: To get a random number you can use the 'rand()' function. To be able to use it you must include "stdlib.h" at the beginning of you program. This function generates a number using an algorithm based on a seed. If you don't randomize the seed then you'll always get the same SEQUENCE of random numbers. Even if this doesn't make sense just do the following:

Include the header "time.h" and at the very beginning of your program (just past the 'main()' definition) write in this line:
srand(time(NULL));
This makes the current time the seed so the random numbers that are generated will truly be random. Now to actually USE the function... rand() will return a number from zero to one LESS than the number you moduli it by. So in the following it will return 0, 1, 2, 3, 4, or 5:
rand()%6;
So if you had a variable named 'x' and you wanted to put a number in it that was in the range of zero to 100 you'd do the following:
x = rand()%101;
Therefore if you needed a different range (like 5 - 10 example), you'd need to do some simple adding. Let's say we wanted a number from 5 to 10. That's six possibilities (5, 6, 7, 8, 9, 10), so we'd moduli by 6 (0, 1, 2, 3, 4, 5) and add 5:
x = rand()%6 + 5;
Whatever the return is will be added to the number 5. So if it returned the maximum (5) then the result (after adding) would be 10. And if it returned the minimum (0) then the result (after adding) would be 5. So we get that range that we need.

Using modulus sometimes seems like a hastle, especially if you're not used to it. What you can do is make a function of your own, that takes a range and then returns a random number in that range. Below is an example of such a function.
// ------------------------------------------------------------------
#include <iostream.h>
#include <stdlib.h>
#include <time.h>

int rnd(int min, int max);

int main()
{
  srand(time(NULL));
  cout << "Random number in the range of 1-5: " << rnd(1,5) << endl;
  cout << "Range of 16-31: " << rnd(16,31) << endl;
  return 0;
}

int rnd(int min, int max)
{
  return (rand()%(max-min+1))+min;
}
// ------------------------------------------------------------------
A breakdown of the one and only line of our 'rnd' function would be as follows if we were getting a number from 5 to 10:
(rand()%(10-5+1))+5;
(rand()%(   5+1))+5;
(rand()%((  6  ))+5;
 rand()%6+5;
A better example would be 121 to 253:
(rand()%(253-121+1))+121;
(rand()%(    132+1))+121;
(rand()%(    133  ))+121
 rand()%133+121;
And that's that.

QUESTIONS: Passing Enumerated Types
Q: Hey Neil...Can you pass enumerated types??...If so, HOW?

A: Sure you can! And I believe all compilers treat enumerations as integers so you COULD have the function parameter type set up as that:
// ------------------------------------------------------------------
#include <iostream.h>

enum BOOL { True = 1, False = 0 };
void function (int n);

int main()
{
  BOOL x;
  x = TRUE;
  function(x);
  return 0;
}

void function (int n)
{
  cout << "You passed: " << n << endl;
}
// ------------------------------------------------------------------
Or you can explicitely tell the compiler that the parameter you want to pass is of a specific enumerated type like in the following:
// ------------------------------------------------------------------
#include <iostream.h>

enum Month
{
  January = 0, February = 1, March = 2, April = 3, May = 4, June = 5,
  July = 6, August = 7, September = 8, October = 9, November = 10,
  December = 11
};

int function(Month m);

int main()
{
  Month mon;

  mon = August;
  cout << "The month selected is \"";
  function(mon);
  cout << "\"" << endl;

  return 0;
}

int function(Month m)
{
  switch(m)
  {
    case January:
      cout << "January";
      break;
    case February:
      cout << "February";
      break;
    case March:
      cout << "March";
      break;
    case April:
      cout << "April";
      break;
    case May:
      cout << "May";
      break;
    case June:
      cout << "June";
      break;
    case July:
      cout << "July";
      break;
    case August:
      cout << "August";
      break;
    case September:
      cout << "September";
      break;
    case October:
      cout << "October";
      break;
    case November:
      cout << "November";
      break;
    case December:
      cout << "December";
      break;
  }
  return 0;
}
// ------------------------------------------------------------------
Hope this helps! Good luck in your class!

QUESTIONS: Basic Menu System
Q: In C++ how do you create a menu, in dos, were the user gets to choose an option and the program will execute it. For example, the user can create a new phone number or look at some old ones. What I am stuck with is how to get the program to branch off, in other words, IF this THEN this. I hope I made it clear enough, thanks.

A: This is a fairly advanced topic because it requires input, flow control, etc. What I suggest for some sort of beginning menu would be:
// ------------------------------------------------------------------
#include <iostream.h>

int do_process_1();
int do_process_2();

int main()
{
  char like_to_continue;
  int process_number;

  do
  {
    cout << "Type a menu option number and press enter" << endl;
    cout << "[1] Do First Process" << endl;
    cout << "[2] Do Second Process" << endl;
    cout << "[-->";
    cin >> process_number;

    if (process_number == 1)
      do_process_1();
    else if (process_number == 2)
      do_process_2();
    else
      cout << "Unknown process!" << endl;

    cout << endl << "Would you like to continue (y/n)?";
    cin >> like_to_continue;

  } while (like_to_contine == 'y' || like_to_continue == 'Y');

  return 0;
}

int do_process_1()
{
  cout << "Doing first process ... DONE (that was quick)" << endl;
  return 0;
}

int do_process_2()
{
  cout << "Doing second process ... DONE (that was quick)" << endl;
  return 0;
}

// ------------------------------------------------------------------
This is untested code, but I think it will work. =) Hope this helps!

QUESTIONS: Returning Strings From Functions
Q: Nice Site - Lots of specific information, but could you tell me how to return a string (or its pointer) from a function and get it into a char array in main()? I have tried something like this, but it truncates the string I passed to four characters and the null terminator:
//sketchy program:
char * function() {
 char n[10];
 strcpy(n, "Monday");
 return n;
} 
main() {
 char a[10];
 strcpy(a, function());
 cout << a << '\n'; //prints "Mond"
}
A: You're lucky you get anything back at all from that function :). The reason being is that 'char n[10]' is a LOCAL variable. This means that the data and the variable itself is trashed when the function returns. You were lucky enough that four of the original characters were still in the same place when you got back to "main()" =). To solve this you can make 'n' in 'function()' not die until the program exits. Simply put the word "static" in front of "char n[10]" and this program will work.

The little word "static" (when used in a function) tells the compiler not to screw with the variable after the function exits which means it still exists, still keeps its value, and is not recreated when the function is called again. Example, you could make a simple counter function using "static". Check this out:
// ------------------------------------------------------------------
#include <iostream.h>

int counter();

int main()
{
  cout << "The counter is " << counter() << endl;
  cout << "The counter is " << counter() << endl;
  cout << "The counter is " << counter() << endl;
  cout << "The counter is " << counter() << endl;
  cout << "The counter is " << counter() << endl;
  cout << "The counter is " << counter() << endl;
  return 0;
}

int counter()
{
  static int keep_count=-1;  //initialize keep_count to minus 1
  return (++keep_count);     //add one to keep_count and return it
}

// ------------------------------------------------------------------
The value of keep_count is not destroyed or reinitialized to '-1' even after the function returns. This means that when you call it a second time its value is zero and becomes one which is returned. The third time its value is one and becomes two, etc. etc.

So back in the case of your string example, it will keep that specified memory for 'n[10]' for the course of you're entire program. So when you want to get information from it (via your strcpy() in main()), you can do it successfully.

QUESTIONS: Visual C++ VS C++
Q: What is the difference between Visual C++ and C++?

A: I found an answer to this on comp.lang.c++ which I much rather liked better than anything else I might have said:

"It's a bit like asking, what's the difference between a car and a Honda Civic.

The difference between C++ and Visual C++(tm) is that one is the name of a language and one is the brand name of a particular product.
" - Matt Austern


The End (for now, *muh ha ha ha*)

Page Content & Design ©1998
By Neil C. Obremski

home

prfce

loop

refs

ptrs

struct

class

array

rsrc

site

indx