Home > Mobile >  How to avoid multiple if-else statement while reading a file?
How to avoid multiple if-else statement while reading a file?

Time:07-06

I am trying to change multiple if-else statement in my program with either switch and enum or some other object-oriented approach. My purpose is in my code there should not be if-else or very less.

class myClass
{
   void readFile();
}  

void myClass :: readFile()
{
     std::string lineByLine;
     std::ifstream myfile;
     myfile.open(file path);
     if (myfile.is_open()) 
     {
        while (std::getline(myfile, lineByLine)) 
       {
           std::pair<std::string, std::string> p1 = FindFirstWord(lineByLine);
           // FindFirstWord --> will break the line into 2 words, First word and remaining words
           
          while (p1.first.compare("}")) {
                if (!p1.first.compare("SCALE")) {
                      // calling some function
                } else {
                    if (!p1.first.compare("symbol")) {
                         // calling some function
                       } else {
                        if (!p1.first.compare("set_minimum_boundary")) {
                              // calling some function
                        } else {
                            if (!p1.first.compare("line")) {
                                // calling some function
                            } else {
                                if (!p1.first.compare("circle")) {
                                    // calling some function
                                    } else {
                                    if (!p1.first.compare("arc")) {
                                        // calling some function
                                       } else {
                                        if (!p1.first.compare("pin")) {
                                            // calling some function
                                       }
                                    }
                                }
                            }
                         }
                     }
                 }

I want to remove the chain of if-else statement using either by switch and enum or some other object oriented approach.

CodePudding user response:

If you want to use an enum with a switch, you can do it in the following way:

Define an enum for your action types:

enum class ActionType
{
    Scale,
    Symbol,
    SetMinimumBoundary,
    //...
    INVALID
};

Add a function for converting a string to the action type enum:

#include <string>
ActionType StringToActionType(std::string const & actionTypeStr)
{
    if (actionTypeStr == "SCALE")                return ActionType::Scale;
    if (actionTypeStr == "symbol")               return ActionType::Symbol;
    if (actionTypeStr == "set_minimum_boundary") return ActionType::SetMinimumBoundary;
    // ...
    return ActionType::INVALID;
}

Then use it as shown below (you can add similar logic to myClass::readFile) :

int main() 
{
    std::string someActionTypeStr;  // Initialized to your p1.first
    ActionType actionType = StringToActionType(someActionTypeStr);
    switch (actionType)
    {
    case ActionType::Scale:  // calling some function   
        break;
    case ActionType::Symbol:  // calling some function  
        break;
    case ActionType::SetMinimumBoundary:  // calling some function  
        break;
    // ... 
    default:
        // report error ...
        break;
    }

    return 0;
}

CodePudding user response:

Use a mapping from keyword to handling functions, this is a quick draft of that idea. (You might want to lookup lambda functions)

#include <functional>
#include <iostream>
#include <string>
#include <sstream>
#include <unordered_map>

std::istringstream filestream
{
    "SCALE\n"
    "symbol\n"
};

class myClass
{
public:
    myClass() :
        m_handlers
        {
            {"SCALE", [=]() { HandleScale(); }},
            {"symbol", [=]() { HandleSymbol(); }}
        }
    {
    };

    void readFile(std::istream& myfile)
    {
        std::string keyword;
        while (myfile >> keyword)
        {
            // skipped line parsing, to show minimal sample
            // lookup if there is a handler for read keyword
            auto it = m_handlers.find(keyword);
            if ( it != m_handlers.end())
            {
                auto& callback = it->second;
                callback();
            }
        }
    }

    void HandleScale()
    {
        std::cout << "handling scale\n";
    }

    void HandleSymbol()
    {
        std::cout << "handling symbol\n";
    }

private:
    std::unordered_map<std::string, std::function<void()>> m_handlers;
};

int main()
{
    myClass object;
    object.readFile(filestream);
    return 0;
}
  • Related