Thread: Command Prompt Shell

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    118

    Command Prompt Shell

    I know it will sound weird at first, but I am trying to make a sort of wrapper around the Windows Command Prompt. The reason for this being that my school blocks windows' Command Prompt (and for good reason, some of the kids don't know squat about computers, and could really screw things up).

    Here's what I have so far:

    Code:
    /*
    
    Wrapper around the microsoft terminal.
    
    Useful for when shell work is not available or disabled.
    
    */
    
    
    
    // Includes start here...
    
    #include <windows.h>
    
    #include <stdlib.h>
    
    #include <iostream>
    
    #include <string>
    
    // Includes end here...
    
    
    
    // Tell that were gonna use some namespaces here...
    
    using namespace std;
    
    
    
    int main()
    
    {
    
    	bool 		quit 		= false;
    
    	string 		cwd         = "> ";
    
    	string      quitstr1    = "quit";
    
    	string      quitstr2    = "Quit";
    
    	string		gettext;
    
    
    
    	// Lets get the user name for nice display at the start of each line...
    
        char        currentuser[50];
    
        DWORD       ncurrentuser   = sizeof(currentuser);
    
    
    
        GetUserName(currentuser, &ncurrentuser);
    
    
    
        start:
    
    
    
    	while(quit == false)
    
    	{
    
    		gettext = "";
    
    		cout	<< currentuser << cwd;
    
    		cin		>> gettext;
    
    		cin.ignore();
    
    
    
            if(gettext == quitstr1 || gettext == quitstr2)
    
            {
    
                quit = true;
    
                goto start;
    
            }
    
    
    
    		system(gettext.c_str());
    
    	}
    
    
    
    	return 0;
    
    }
    I know this isn't quite the best solution, but it is a quick hack-up that will hopefully work when I try and use portable gcc at the schools computers (among other things that need the terminal).

    My question is...

    I want to give the program the ability to use the cd command. And what I'm thinking for this, is just to see if the user inputted 'cd C:\whatever', like I did with quit. Problem is, how to I just collect the first two characters, to see if it's 'cd'? And even if I do this, how to I collect everything after the third character (everything after 'cd<space>')? If I can just do this, I'll be able to append that path to './whatever.txt' files, so that the user doesn't always have to use full path names.

    Thanks so much!
    FlyingIsFun1217

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Problem is, how to I just collect the first two characters, to see if it's 'cd'?
    It seems to me that locating the first whitespace character would be a better solution, after which you can take the substring based on that. std::string makes this easy.

    By the way, there is no need to use goto in your program. Use a loop.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by laserlight View Post
    By the way, there is no need to use goto in your program. Use a loop.
    Or in this case use break.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    118
    Quote Originally Posted by laserlight View Post
    By the way, there is no need to use goto in your program. Use a loop.
    I figure the code is small enough and not too horribly public, so I don't see why using a goto would be a bad idea.

    I can search around easy enough to find how to find the first whitespace, but what exactly do you mean by 'taking the substring based on that'? Find the whitespace, and check to see what is before/after it?

    Thanks again!
    FlyingIsFun1217

  5. #5
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by FlyingIsFun1217 View Post
    I figure the code is small enough and not too horribly public, so I don't see why using a goto would be a bad idea.
    many code does start small and "not too horribly public". and then it grows. and then nobody has time to clean it up and nobody want to throw it away. And some rainy day some poor programmer writes a desperated post to this board about how to fix the messed up spaghetti-goto program he should maintain because the creator is to busy writing new spaghetti code elsewhere. just do it right. you won't lose anything

    Quote Originally Posted by FlyingIsFun1217 View Post
    I can search around easy enough to find how to find the first whitespace, but what exactly do you mean by 'taking the substring based on that'? Find the whitespace, and check to see what is before/after it?

    Thanks again!
    FlyingIsFun1217
    Code:
    if
    (
        yourString.substring(0, yourString.find(string(" ")))
        ==
        string("cd")
    )
    {
      // you got  a string starting with "cd"
    }

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    118
    Quote Originally Posted by pheres View Post
    many code does start small and "not too horribly public". and then it grows. and then nobody has time to clean it up and nobody want to throw it away. And some rainy day some poor programmer writes a desperated post to this board about how to fix the messed up spaghetti-goto program he should maintain because the creator is to busy writing new spaghetti code elsewhere. just do it right. you won't lose anything
    I mean for this to be a mostly personal project, and I'm sure that the code is so messed up anyway, that I would hope others DON'T use it. But alas, to fall into peer pressure and clean up code, I will use a break.

    Quote Originally Posted by pheres View Post
    Code:
    if
    (
        yourString.substring(0, yourString.find(string(" ")))
        ==
        string("cd")
    )
    {
      // you got  a string starting with "cd"
    }
    Very helpful! Guess I better have looked over my reading better.
    I will read through my C++ book, but... and this is why I am going to read through my book, because it will sound kinda rude... how would I best be able to get the path from the user? Would it be to look for the fourth entry?

    FlyingIsFun1217

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Code:
    string path;
    string::size_type first_space = yourString.find(string(" "));
    if
    (
        yourString.substring(0, first_space)
        ==
        string("cd")
    )
    {
      // you got  a string starting with "cd"
      // now get the path
       path = yourString.substring(first_space);
    
      // now take the path string and break it into it's components.
      // therefore search for "\" or "/"
      // depending on your system
      // ...left to the reader ;)
    }
    just written out of my head.
    http://www.sgi.com/tech/stl/basic_string.html
    will help you
    Last edited by pheres; 09-16-2007 at 04:40 PM.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by FlyingIsFun1217 View Post
    I figure the code is small enough and not too horribly public, so I don't see why using a goto would be a bad idea.
    You don't write maintainable code to avoid being embarrassed in public. You write maintainable code because it's maintainable.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    118
    Quote Originally Posted by CornedBee View Post
    You don't write maintainable code to avoid being embarrassed in public. You write maintainable code because it's maintainable.
    I don't plan on maintaining this when I'm done

    Thanks for the example, and especially the link!

    FlyingIsFun1217

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I don't plan on maintaining this when I'm done

    Of course, the other reason to write maintainable code is to get in the habit of doing it for the time when you do plan on maintaining your code.

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    118
    Quote Originally Posted by Daved View Post
    >> I don't plan on maintaining this when I'm done

    Of course, the other reason to write maintainable code is to get in the habit of doing it for the time when you do plan on maintaining your code.
    Very true...

    FlyingIsFun1217

  12. #12
    Registered User
    Join Date
    Oct 2006
    Posts
    118
    Hola amigos!

    Here's my current code:

    Code:
    /*
    Wrapper around the microsoft terminal.
    Useful for when shell work is not available or disabled.
    */
    
    // Includes start here...
    #include <windows.h>
    #include <stdlib.h>
    #include <iostream>
    #include <string>
    // Includes end here...
    
    // Tell that were gonna use some namespaces here...
    using namespace std;
    
    int main()
    {
    	bool 		quit 		= false;
    	string 		cwd         = "> ";
    	string      quitstr1    = "quit";
    	string      quitstr2    = "Quit";
    	string		gettext;
    
    	// Lets get the user name for nice display at the start of each line...
        char        currentuser[50];
        DWORD       ncurrentuser   = sizeof(currentuser);
    
        GetUserName(currentuser, &ncurrentuser);
    
    	while(quit == false)
    	{
    		gettext = "";
    		cout	<< currentuser << cwd;
    		cin		>> gettext;
    		cin.ignore();
    
            if(gettext == quitstr1 || gettext == quitstr2)
            {
                quit = true;
                break;
            }
    
            // Check for 'CD...', give a string containing first two letters...
            string cdstring = gettext.substr(0,2);
            // Conditional strings to check for 'CD', 'Cd', 'cD', 'cd',...
            string cd1 = "CD";
            string cd2 = "Cd";
            string cd3 = "cD";
            string cd4 = "cd";
            // Store current directory in this string. ABSOLUTE DEFINITIVE DIRECTORY HOLDER!
            string currentdirectory = "";
    
            if(cdstring == cd1 || cdstring == cd2 || cdstring == cd3 || cdstring == cd4)
            {
                string tempdirectory = gettext.substr(3,65);
                currentdirectory = tempdirectory;
    
                tempdirectory.erase(0,tempdirectory.length());
            }
    
    		system(gettext.c_str());
    	}
    
    	return 0;
    }
    Seems though that when I type in at my 'shell': cd <whateverhere>, I just get an unexpected error, reported when running through C::B as:

    This application has requested the Runtime to terminate it in an unusual way. Please contact the applications support team for more information.
    Running it standalone though just gives me the result of the program instantaneously closing.

    Any thoughts on this one?
    FlyingIsFun1217

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    substr() asserts (or even throws, not sure) if any index is out of range. Your generous (3, 65) substring is probably out of range most of the time.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Surely there is a way to compare strings in a case-insensitive way - if nothing else, create a lower or upper case copy of your string, and compare it to your command - imagine the number of combinations of "mkdir" (32 combinations) or "delete" (64 combinations) for example - you'd be forever writing command comparisons.

    The other thought on this subject is that you probably want to create a structure/class with command and function pointers to make the parsing and implementation of new commands easier. You may also want to take your input string and split it at spaces into a int argc, char *argv[] set. That way, you can easily sort out things like "rmdir /s directory-to-delete" [well, at least it's EASIER than if in each command you go about splitting the string into pieces].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Registered User
    Join Date
    Oct 2006
    Posts
    118
    Quote Originally Posted by matsp View Post
    Surely there is a way to compare strings in a case-insensitive way - if nothing else, create a lower or upper case copy of your string, and compare it to your command - imagine the number of combinations of "mkdir" (32 combinations) or "delete" (64 combinations) for example - you'd be forever writing command comparisons.

    The other thought on this subject is that you probably want to create a structure/class with command and function pointers to make the parsing and implementation of new commands easier. You may also want to take your input string and split it at spaces into a int argc, char *argv[] set. That way, you can easily sort out things like "rmdir /s directory-to-delete" [well, at least it's EASIER than if in each command you go about splitting the string into pieces].

    --
    Mats
    Still doesn't explain my current error though, which is what I'm most interested in at the moment...

    Good tips though, I will definitely split it up into separate functions soon

    FlyingIsFun1217

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 34
    Last Post: 05-27-2009, 12:26 PM
  2. What shell is more powerful?
    By xddxogm3 in forum Tech Board
    Replies: 10
    Last Post: 07-24-2004, 10:47 PM
  3. System.ini Shell Problems
    By (TNT) in forum Windows Programming
    Replies: 2
    Last Post: 08-26-2001, 01:05 PM