1

I'm creating a command line symbols generator. The idea is when you call the program with a symbol name it outputs the symbol. I wonder if I can pass the input string as a command to cout.

For every symbol I add I have to manually add "else if" statement.

#include <bits/stdc++.h>
using namespace std;

string const notfound = R"~(

                         ______                     
 _________        .---"""      """---.              
:______.-':      :  .--------------.  :             
| ______  |      | :                : |             
|:______B:|      | |  Little Error: | |             
|:______B:|      | |                | |             
|:______B:|      | |  Symbol not    | |             
|         |      | |  found.        | |             
|:_____:  |      | |                | |             
|    ==   |      | :                : |             
|       O |      :  '--------------'  :             
|       o |      :'---...______...---'              
|       o |-._.-i___/'             \._              
|'-.____o_|   '-.   '-...______...-'   -._          
:_________:       .____________________    -.___.-. 
                 .'.eeeeeeeeeeeeeeeeee.'.      :___:
               .'.eeeeeeeeeeeeeeeeeeeeee.'.         
              :____________________________:

)~";
string const butterfly = R"~(
                              $¶¶$¶¶$¶$
                           $¶¶$ø¢¢øø17¶$
                          ¶¢1 7oøoø o7¶1
 11¶¶¶¶¶¶¶¶¶ø           ø¶ø 1oø¢o1ø o¶¢ 
¶¶¢¶ø¢¢¢¢77oø¶¶¶        ¶¢7ø$øoo7o$77¶o 
¶¶7 7o77177777oø¶¶1    ¶øooo77777oø7¶¶
 ¶¶¶7o¢øø77ø¢ooooø¶¶¶¶¶¶¢oooo7177¢7o¶7
   ¶¶7 oooooooo77177o7øø¢¢ø¢ooooøø¢¶
    7¶¢o7¢øoo7717oøø¶¶øoø¢ooo¢¢ooooo$7
     7¶¶ø17oo7oø¶øøooøooooo777o¢oo71 o¶1
       1¶¶$oø$$¢111¢1o¶¶ø7oøøo7ooooø7¢1¶
         ø177 o1 ooo ¢ø ¶ø7oooø¢oo1¢1ø7¶
        ¶¢¢7o7oo¢oøo ø¶  ¶¶ooo77o7ø¶1 o¶
       1ø$oøo1øø¢¢7o ¶ø   ø¶¢$$¢$¶77oø¶7
       7¶17ø77¢7711¶7¶      ¢¢ø   71¢¶1
        ø¶$¢øø71oøø¢¢¶        øø¶¶¶¶¶o
         7¶oø¶¶¶¢77¶¶ 
           $¶¶ø¢¶¶¶7 
)~";

void Print_Symbol(string x){
    if(x == "butterfly")
        cout<<butterfly<<endl;
        // Add else if for every new symbol
    else
    cout<<notfound<<endl;

}
int main(int argc,char* argv[]){
    if(argc < 2){
        cout<<"To get a symbol enter: sym Symbol_Name"<<'\n';
        cout<<"Available Symbols: "<<'\n';
        cout<<"hello, hi,butterfly,.."<<'\n';
    }
    for(int i=1;i<argc;i++){
        string x = argv[i];
        Print_Symbol(x);
    }
    return 0;
}

With few symbols this isn't a problem. But when I move the symbols to another file, I want to be able to add a symbol without recompiling the main program

Is it possible to do it like this

int main(int argc,char* argv[]){
    if(argc < 2){
        cout<<"To get a symbol enter: sym Symbol_Name"<<'\n';
        cout<<"Available Symbols: "<<'\n';
        cout<<"hello, hi,butterfly,.."<<'\n';
    }
    for(int i=1;i<argc;i++){
        string x = argv[i];
          // pass the string to cout
        cout<<x<<'\n';
    }
    return 0;
}
  • 2
    Time to get a couple of [good C++ books to read](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) and learn C++ properly. For example about the [standard cotnainers](https://en.cppreference.com/w/cpp/container) like [`std::unordered_map`](https://en.cppreference.com/w/cpp/container/unordered_map). – Some programmer dude Jul 19 '19 at 11:20
  • 1
    And please take some time to read [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – Some programmer dude Jul 19 '19 at 11:26
  • Thank you, your answer was very helpful. And I only use bits/stdc++.h because I'm into competitive programming, I will not use it in any other way. – AmineTrabelsi Jul 19 '19 at 11:28
  • 1
    That header is useless in competitive programming as well, all it does is increase your compile time unnecessary. And all you will learn by using online judges and competition sites is to become good at those sites only, you won't really learn anything that can be useful for, for example, working with programming. Study programming and C++ *first*, then when you're comfortable with the language, knows the standard library pretty well, and have some knowledge of common algorithms and data structures, then you'll excel at those sites. – Some programmer dude Jul 19 '19 at 11:34
  • I give you same Answer ... – Nikola Lukic Jul 21 '19 at 20:15

2 Answers2

2

C++ is a static language. I don't see how you can do that, at least not yet. But to bypass else/if statements there are multiple ways.

Solution 1: Use std::map

By using the std::map template class, and a simple std::find you can avoid using else if statements.

void Print_Symbol(string x){
    static const std::map<string, string> symbs ({
        {"butterfly", butterfly} // add more here
    });
    auto res = symbs.find(x);
    if (res == symbs.end())
       cout<< notfound <<endl;
    else
       cout << *res << endl;
}

Solution 2: Use std::vector or ...

Practically the same as solution 1.

Solution 3: Use files

In your case you can put each symbol in its own file and what the user inputs, is the file name.

Solution 4: Use switch case

I know in c++ you can't use strings in switch cases, but you can convert each string to a number, then put those in switch case. I don't recommend it for here though.


There are other solutions but I'm afraid they are not suitable for this problem you're having (the same as solution 4).

The Moisrex
  • 1,857
  • 1
  • 14
  • 16
  • I will be using files but the problem is I don't want to insert the file name manually to the code, I want to be able to print the symbol just after adding it to the files – AmineTrabelsi Jul 19 '19 at 12:27
  • 1
    it's easy actually, you can check if the file exists, if it doesn't, then you can just print the default one. It's not that hard to check if the file exists or not. – The Moisrex Jul 19 '19 at 12:30
0

You can improve this code in your manner also there is other's ways like eval. It is important to say security aspect can be critical when you allow to execute literal injected content(code).

#include <bits/stdc++.h>
using namespace std;

string const notfound = R"~(

                         ______                     
 _________        .---"""      """---.              
:______.-':      :  .--------------.  :             
| ______  |      | :                : |             
|:______B:|      | |  Little Error: | |             
|:______B:|      | |                | |             
|:______B:|      | |  Symbol not    | |             
|         |      | |  found.        | |             
|:_____:  |      | |                | |             
|    ==   |      | :                : |             
|       O |      :  '--------------'  :             
|       o |      :'---...______...---'              
|       o |-._.-i___/'             \._              
|'-.____o_|   '-.   '-...______...-'   -._          
:_________:       .____________________    -.___.-. 
                 .'.eeeeeeeeeeeeeeeeee.'.      :___:
               .'.eeeeeeeeeeeeeeeeeeeeee.'.         
              :____________________________:

)~";
string const butterfly = R"~(
                              $¶¶$¶¶$¶$
                           $¶¶$ø¢¢øø17¶$
                          ¶¢1 7oøoø o7¶1
 11¶¶¶¶¶¶¶¶¶ø           ø¶ø 1oø¢o1ø o¶¢ 
¶¶¢¶ø¢¢¢¢77oø¶¶¶        ¶¢7ø$øoo7o$77¶o 
¶¶7 7o77177777oø¶¶1    ¶øooo77777oø7¶¶
 ¶¶¶7o¢øø77ø¢ooooø¶¶¶¶¶¶¢oooo7177¢7o¶7
   ¶¶7 oooooooo77177o7øø¢¢ø¢ooooøø¢¶
    7¶¢o7¢øoo7717oøø¶¶øoø¢ooo¢¢ooooo$7
     7¶¶ø17oo7oø¶øøooøooooo777o¢oo71 o¶1
       1¶¶$oø$$¢111¢1o¶¶ø7oøøo7ooooø7¢1¶
         ø177 o1 ooo ¢ø ¶ø7oooø¢oo1¢1ø7¶
        ¶¢¢7o7oo¢oøo ø¶  ¶¶ooo77o7ø¶1 o¶
       1ø$oøo1øø¢¢7o ¶ø   ø¶¢$$¢$¶77oø¶7
       7¶17ø77¢7711¶7¶      ¢¢ø   71¢¶1
        ø¶$¢øø71oøø¢¢¶        øø¶¶¶¶¶o
         7¶oø¶¶¶¢77¶¶ 
           $¶¶ø¢¶¶¶7 
)~";

void Print_Symbol(string x){
    if(x == "butterfly")
        cout<<butterfly<<endl;
        // Add else if for every new symbol
    else
    cout<<notfound<<endl;

}

void executeMe() { 

    Print_Symbol("butterfly");
    std::cout << "executeMe()"; 


}

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

    std::map<std::string, std::function<void()>> functions;

    functions["executeMe"] = executeMe;

    if(argc < 2){
        cout<<"To get a symbol enter: sym Symbol_Name"<<'\n';
        cout<<"Available Symbols: "<<'\n';
        cout<<"hello, hi,butterfly,.."<<'\n';
    }

    for(int i=0;i<argc;i++){
        string x = argv[i];
        if (functions.find(x) != functions.end()) {
          cout << " test " << x << endl;
          functions[x]();
        }

    }
    return 0;
}
Nikola Lukic
  • 4,001
  • 6
  • 44
  • 75