passing arguments

This is a discussion on passing arguments within the C++ Programming forums, part of the General Programming Boards category; Hey, See below for sourcecode. The program will eventually be a locate like the one from the UNIX shell. Function ...

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    6

    Question passing arguments

    Hey,
    See below for sourcecode. The program will eventually be a locate like the one from the UNIX shell. Function CreateDataBase() needs to know what drives it should include in the DataBase. There are three options:
    1) All harddisks (default)
    2) All logical drives (activated by /a command-line argument)
    3) Specified drives (activated by /d followed by drive-letters in the command-line)

    The CreateDataBase() function calls LogicDrives() for the first two options. For the third option, DrivesFromArgs() is called. Obviously, DrivesFromArgs() needs the command-line arguments to function. I've thought of a couple of ways to provide DrivesFromArgs() these variables, but they're not too pretty. This is what I thought of:

    1) Make argc and *argv[] global variables
    2) Pass argc and *argv[] to CreateDataBase, then pass them on to DrivesFromArgs() (if needed)
    3) Create a special function that extracts the specified drives from the arguments, passes the variable on to CreateDataBase, and then pass it on to DrivesFromArgs()

    I don't like the last two because it will make CreateDataBase() have more arguments than normally needed.
    Is there a better method to do this than the three I thought of, or should I just use one of those?

    Thanks!

    -Joris


    Code:
    #include <windows.h>
    #include <iostream.h>
    #include <math.h>
    
    DWORD OptionFlags = 0;
    
    inline bool BitTrue(DWORD a, DWORD b) { return (a & (1 << b)) ? true : false; } //Is bit 1?
    inline void DefBit(DWORD &a, DWORD b) { a = (a | (1 <<  b)); } //define bit
    inline void UnDefBit(DWORD &a, DWORD b) { a = DWORD(4294967295 - pow(2, b)) & a; } //undefine bit
    
    DWORD LogicDrives(bool HDsOnly) //All Logical drives or Harddisks only
    {	
    	DWORD Drivelist = GetLogicalDrives();
    	
    	if (HDsOnly)
    	{
    		char DriveCheck[4] = "*:\\";
    		for (int a = 0; a < 26; a++)
    		{	
    			if (BitTrue(Drivelist, a)) 
    			{
    				DriveCheck[0]= 'A'+a;
    				UnDefBit(Drivelist, a);
    				if (GetDriveType(DriveCheck)==3) DefBit(Drivelist, a); //Check if it's a HD
    			}
    		}
    	}
    	
    	return Drivelist;
    }
    
    DWORD DrivesFromArgs() //Drives from arguments
    {
    	DWORD Drives = 0;
    	for(int a = 0; a < 26; a++) DefBit(Drives, a); //Sets all drives
    	return Drives;
    }
    
    
    
    DWORD Options(int argc, char *argv[]) //Get Options from arguments
    {	
    	DWORD Flags=0;
    	for(int a = 1; a < argc; a++)
    	{
    		if (argv[a][0] == '/')
    		{
    			switch (argv[a][1])
    				{
    					case 'C': case 'c': DefBit(Flags, 0); break; //Create DB
    					case 'V': case 'v': DefBit(Flags, 1); break; //Verbose mode
    					case 'D': case 'd': DefBit(Flags, 2); break; //Specified drives in args
    					case 'A': case 'a': DefBit(Flags, 3); break; //All logical drives
    				}
    		}
    	}
    	return Flags;
    }
    
    
    
    void Say(int LineNum, int a=0,DWORD Flags=0) //Output a line
    {
    	int b = 0;
    
    	switch (LineNum) //will always be said
    	{
    		case 0: cout << "Start of program" << endl; return;
    		case 1: cout << "End of program" << endl; return;
    	}
    	
    	
    	if (BitTrue(OptionFlags, 1)) //will only be said in verbose mode
    	{
    		switch (LineNum)
    		{
    			case 100: cout << a << " arguments: "; for(;b < 10;b++) cout << BitTrue(Flags, b); cout << endl; return;
    			case 101: cout << "Creating database" << endl; return;
    			case 102: cout << "Drives to index: "; for(;b < 26;b++) cout << BitTrue(Flags, b); cout << endl; return;
    		}
    	}
    }
    
    
    void CreateDatabase() //Creates a database
    {
    	Say(101);
    	DWORD DrivesToIndex;
    		
    	if (BitTrue(OptionFlags, 2)) DrivesToIndex = DrivesFromArgs(); //Get drives from arguments
    	else if (BitTrue(OptionFlags, 3)) DrivesToIndex = LogicDrives(false); //Do All logic drives
    	else DrivesToIndex = LogicDrives(true); //Do all HDs
    	
    	Say(102,0,DrivesToIndex);
    }
    
    int main(int argc, char *argv[]) //main
    {
    	Say(0);	
    	OptionFlags = Options(argc, argv); //get options
    	Say(100, argc-1, OptionFlags);
    	if (BitTrue(OptionFlags, 0)) CreateDatabase();
    	Say(1);
    	return 0;
    }

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >1) Make argc and *argv[] global variables
    Not the best idea.

    >2) Pass argc and *argv[] to CreateDataBase, then pass them on to DrivesFromArgs() (if needed)
    I see nothing wrong with this.

    >3) Create a special function that extracts the specified drives from the arguments, passes the variable on to CreateDataBase, and then pass it on to DrivesFromArgs()
    The logic is a little too backward for my taste.

    >Is there a better method to do this than the three I thought of
    Have you considered using a class to bundle all of this up into a single object?
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Dec 2003
    Posts
    6
    With "all of this" you mean argc and *argv[]? Might be a good idea, hadn't thought about that one. But what I don't like about solutions like this one and my personal second and third, is that CreateDataBase() needs another argument that it won't need for itself (it only needs to pass it on to another function) and in most cases won't be needed at all (only when /d is used).
    But maybe I'm just too obsessed by efficiency. I justed started programming C++ for two weeks or so and this is the first program I'm building so this is the first time I'm calling functions from within functions.

  4. #4
    Registered User
    Join Date
    May 2003
    Posts
    161
    > With "all of this" you mean argc and *argv[]?

    She means put it all in a class. You can pass argc and **argv as constructor arguments and then store them as member variables so that all of your functions will have access to them. It might look something like this:

    Code:
    // .. class definition
    class LocateClass
    {
    public:
      LocateClass(int argc_, char** argv_)
      : argc(argc_), argv(argv_)
      {}
    
      void locate()
      {
        Say(0);
        ParseOptions();
        if (BitTrue(OptionFlags, 0)) CreateDatabase();
        Say(1);
      }
      // .. other functions
    
    private:
      int argc;
      char** argv;
      DWORD OptionFlags;
    };
    
    
    int main(int argc, char** argv)
    {
      LocateClass locator(argc, argv);
      locator.locate();
      return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing arguments to the system
    By ech0wave in forum C Programming
    Replies: 6
    Last Post: 05-07-2009, 11:15 AM
  2. Passing arguments
    By jcafaro10 in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2009, 12:14 PM
  3. Replies: 7
    Last Post: 11-21-2008, 03:27 PM
  4. A question about passing arguments
    By AntiScience in forum C++ Programming
    Replies: 10
    Last Post: 10-16-2007, 02:42 PM
  5. Passing arguments between functions
    By Wiretron in forum C Programming
    Replies: 4
    Last Post: 05-17-2006, 04:59 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21