Thread: Calling functions

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    4

    Calling functions

    Hi,

    I'm trying to make a function wich calls other functions based on user input.
    Example:
    I type help and the program executes the function help.

    Can this be done, if so how?

    any help will be greatly apreciated

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    To some extent, yes, this can be done. One way is to map the "command" names to the corresponding function pointers, then after reading user input, search for the name, get the corresponding key, and then call the function. If the functions may have different signatures, you probably would need a hierarchy of function objects instead if you want to make use of std::map for the mapping.
    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
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You would have to write some code that "translates" the string help to a call to the function help. In the simplest form, that would look somewhat like this:
    Code:
        char input[maxsize];
        // some code to read input from the user. 
        if (strcmp(input, "help"))
        {
           help();
        }
    There are other solutions that make it easier to write the code and expand the number of functions if there are many functions. But the principle is still a string comparison and a call to the relevant function.

    It is IMPOSSIBLE to make C or C++ directly call a function from a string representing the name, because the name is only there in the source code. Once the compiler has processed the source-code, there is no way to know what the name of a function is.

    I got sidetracked for a bit, hence the rather long time to reply.

    --
    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.

  4. #4
    Registered User
    Join Date
    Feb 2009
    Posts
    4
    thanks laserlight and matsp
    I'll play with both and see what suits my purpose best.

    I think i'll get a long if then else statement if I go with matsp though.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Kreathyr View Post
    thanks laserlight and matsp
    I'll play with both and see what suits my purpose best.

    I think i'll get a long if then else statement if I go with matsp though.
    Laserlights suggestion is a much more C++ solution, and I'd say that's the "proper" way to do it. Mine is the most basic (and actually not C++ at all - but it does describe the most simple solution possible). And I did say that there are better solutions if you have LOTS of functions to call.

    --
    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.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Still, that was a C solution. The equivalent C++ solution would be:
    Code:
        std::string input;
        // some code to read input from the user. 
        if (input == "help") help();
    No need to do it the hard way.
    A sample of laserlight's solution:
    Code:
    // Create and initialize map
    typedef void (fnc_ptr)();
    typedef std::map<std::string, fnc_ptr*> CommandMap_t;
    CommandMap_t CommandMap;
    CommandMap["help"] = &help;
    
    // Get input from user
    std::string input;
    // ...
    
    // Find function and call it
    CommandMap_t::iterator it = CommandMap.find(input);
    if (it)
        it->second(); // Call function
    Not tested for errors.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    As I said in the previous post, my explanation was more to show the BASIC principle. It is indeed a good idea to use a map. However, the basic problem is still that SOMEHOW you need to compare a string with a constant string, and if it is a match, call the relevant function. Now, we can ACHIEVE that in many different ways.

    --
    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.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by matsp View Post
    As I said in the previous post, my explanation was more to show the BASIC principle.
    Yes, I do agree with you, but you used chars and strcmp while you can use std::string and operator == instead (C++ version).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Yes, I do agree with you, but you used chars and strcmp while you can use std::string and operator == instead (C++ version).
    My old C habits tend to stick out now and again, I do admit.

    --
    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.

  10. #10
    Registered User
    Join Date
    Feb 2009
    Posts
    4
    Hi again,

    I tried figuring this map thing out myself, not a big succes...
    Then I tried the example Elysia provided and get the following error when compiling.

    Code:
    B:\help>g++ help.cpp -o help.exe
    help.cpp: In function `int main()':
    help.cpp:23: error: could not convert `it' to `bool'
    I don't know much about C++ yet, but line 23 says:
    Code:
    if (it)
    thanks for all the help so far

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    That is because Elysia was just giving you a rough sketch, not working code. If you want a working example:
    Code:
    #include <iostream>
    #include <map>
    #include <string>
    
    // The dummy functions to call.
    void foo();
    void bar();
    
    typedef void (*Function)();
    typedef std::map<std::string, Function> FunctionMap;
    
    // Print the list of functions.
    void listFunctions(std::ostream& out, const FunctionMap& function_map);
    
    int main()
    {
        using namespace std;
        // Create and populate the function map.
        FunctionMap function_map;
        function_map["foo"] = foo;
        function_map["bar"] = bar;
    
        cout << "The functions are:\n";
        listFunctions(cout, function_map);
    
        string command;
        cout << "Which function would you like to call?\n>";
        cin >> command;
    
        // Find function and call it if it exists.
        FunctionMap::iterator found = function_map.find(command);
        if (found != function_map.end())
        {
            (*found->second)();
        }
        else
        {
            cout << "Sorry, no function with that name exists." << endl;
        }
    }
    
    void foo()
    {
        std::cout << "You have called foo()!" << std::endl;
    }
    
    void bar()
    {
        std::cout << "You have called bar()!" << std::endl;
    }
    
    // Print the list of functions.
    void listFunctions(std::ostream& out, const FunctionMap& function_map)
    {
        for (FunctionMap::const_iterator iter = function_map.begin(), end = function_map.end();
            iter != end; ++iter)
        {
            out << iter->first << '\n';
        }
    }
    I suggest that you read some material on how to use a std::map, e.g., cppreference.com's entry on map.
    Last edited by laserlight; 02-23-2009 at 12:29 AM.
    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

  12. #12
    Registered User
    Join Date
    Feb 2009
    Posts
    4
    Thanks, this one works.

    I'm currently reading trough the reference you mentioned.
    Can't make much op from it, but maybe your example will help.

    Again, thank you very very much.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Elysia
    Code:
    typedef void (fnc_ptr)();
    typedef std::map<std::string, fnc_ptr*> CommandMap_t;
    I understand why you want a function typedef and then declare a pointer to it, instead of the more common function pointer typedef.
    But then, don't call the function type 'fnc_ptr'; it's misleading.
    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
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Kreathyr View Post
    Can this be done?
    Naah, it can't be done. Computers can't do much of anything, really. It's better to use them for target practice.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    I understand why you want a function typedef and then declare a pointer to it, instead of the more common function pointer typedef.
    But then, don't call the function type 'fnc_ptr'; it's misleading.
    Because I don't like to typedef pointers.
    If I do it this way, I have to add the * to it, making it more obvious that it is indeed a pointer.
    But you do have a point on the misleading name... I'll think of it naming it function or something.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 04-12-2009, 05:49 PM
  2. Replies: 9
    Last Post: 01-26-2008, 03:12 AM
  3. calling functions: exit and return
    By 911help in forum C Programming
    Replies: 3
    Last Post: 12-28-2007, 01:24 PM
  4. I Need Help Defining and Calling Functions
    By jonbuckets in forum C++ Programming
    Replies: 6
    Last Post: 10-25-2007, 09:46 AM
  5. Calling functions help
    By ForlornOdium in forum C++ Programming
    Replies: 14
    Last Post: 09-29-2003, 08:40 PM