Moja klasa - CLiniaPolecen

0

Witam :)

Dziś skończyłem swoją klasę do obsługi linii poleceń. Uważam, że jak na mnie - z racji tego, że jestem początkujący - to naprawde przydatne narzędzie i komuś kto szuka czegoś w tym rodzaju może się przydać dlatego zamieszczam jej kod.

CLiniaPolecen.h

// CLiniaPolecen ver 1.03

// Dla uscislenia i unikania niejednoznacznosci
// Polecenie - ciag znakow wprowadzony przez uzytkownika
// Parametr - wydzielona czesc polecenia

#pragma once

#include <string>

using namespace std;

class CLiniaPolecen
{
      private:              
              string polecenie;
              string znakZachety;
              char znakOdstepu;
              char znakPodzialu;
              char znakGrupowania;
                                   
              void Formatuj(); // OK!
              void Blad();
              
      public:
             // Glowne
             CLiniaPolecen(); // OK!
             void Pobierz(); // OK!
             
             // Znak zachety
             void UstawZnakZachety(string ciag); // OK!
             string ZwrocZnakZachety(); // OK!     
             
             // Znak odstepu
             void UstawZnakOdstepu(char c); // OK!
             char ZwrocZnakOdstepu();  // OK!
                          
             // Znak podzialu
             void UstawZnakPodzialu(char c); // OK!
             char ZwrocZnakPodzialu();  // OK!
             
             // Znak grupowania
             void UstawZnakGrupowania(char c); // OK!
             char ZwrocZnakGrupowania(); // OK!
             
             // Parametry
             int ZwrocIlosc(); // OK!
             string Zwroc(int numer); // OK!
             int ZwrocInt(int numer); // OK!
             double ZwrocDouble(int numer); // OK!
             bool Porownaj(string ciag, int numer, bool wrazliwy = false); // OK!
             bool Porownaj(int liczba, int numer); // OK!
             bool Porownaj(double liczba, int numer); // OK!
};

CLiniaPolecen.cpp

#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
#include "CLiniaPolecen.h"

using namespace std;

// Glowne

CLiniaPolecen::CLiniaPolecen() 
{
               znakZachety = ":";
               znakOdstepu = ' ';
               znakPodzialu = '|';
               znakGrupowania = '"';
}

void CLiniaPolecen::Pobierz()
{
     cout << znakZachety;
     getline(cin, polecenie);
     
     Formatuj();
}

// Znak zachety

void CLiniaPolecen::UstawZnakZachety(string ciag)
{
     znakZachety = ciag;
}

string CLiniaPolecen::ZwrocZnakZachety()
{
     return znakZachety;
}

// Znak odstepu

void CLiniaPolecen::UstawZnakOdstepu(char znak)
{
     znakOdstepu = znak;
}

char CLiniaPolecen::ZwrocZnakOdstepu()
{
     return znakOdstepu;
}

// Znak podzialu

void CLiniaPolecen::UstawZnakPodzialu(char znak)
{
     znakPodzialu = znak;
}

char CLiniaPolecen::ZwrocZnakPodzialu()
{
     return znakPodzialu;
}

// Znak grupowania

void CLiniaPolecen::UstawZnakGrupowania(char znak)
{
     znakGrupowania = znak;
}

char CLiniaPolecen::ZwrocZnakGrupowania()
{
     return znakGrupowania;
}

// Parametry

int CLiniaPolecen::ZwrocIlosc()
{
    int j = 0;
    for(int i = 0; i < polecenie.length(); i++) if(polecenie[i] == znakPodzialu) j++;
    
    return --j;
}

string CLiniaPolecen::Zwroc(int numer)
{
       string temp;
       temp.resize(polecenie.length());
       
       int j = -1;
       int k = 0;
       for(int i = 0; i < polecenie.length(); i++)
       {
               if(polecenie[i] == znakPodzialu) j++;
               if(polecenie[i] != znakPodzialu && j == numer) temp[k++] = polecenie[i];
       }
       
       temp.resize(k);
                
       return temp;
}

int CLiniaPolecen::ZwrocInt(int numer)
{
     istringstream rzutowanie(Zwroc(numer));
     
     int liczba;
     
     rzutowanie >> liczba;
     
     return liczba;
}

double CLiniaPolecen::ZwrocDouble(int numer)
{
     double liczba;
     
     liczba = strtod(Zwroc(numer).c_str(), NULL);
     
     return liczba;
}

bool CLiniaPolecen::Porownaj(string ciag, int numer, bool wrazliwy)
{
     string temp = Zwroc(numer);
     
     if(!wrazliwy)
     {
                  for(int i = 0; i < ciag.length(); i++)
                  {
                          ciag[i] = tolower(ciag[i]);
                  }
                  
                  for(int i = 0; i < temp.length(); i++)
                  {
                          temp[i] = tolower(temp[i]);
                  }
     }
     
     if(ciag == temp) return true;
             else return false;
}

bool CLiniaPolecen::Porownaj(int liczba, int numer)
{
     int temp = ZwrocInt(numer);
     
     if(liczba == temp) return true;
               else return false;
}

bool CLiniaPolecen::Porownaj(double liczba, int numer)
{
     double temp = ZwrocDouble(numer);
     
     if(liczba == temp) return true;
               else return false;
}

// Metody prywatne

void CLiniaPolecen::Formatuj()
{
     string ciag = polecenie;  
     string temp;
     
     temp.resize(ciag.length() + 2);
     ciag = znakPodzialu + ciag + znakPodzialu;
     
     int j = 0;
     bool b = false;
     
     for(int i = 1; i < ciag.length() - 1; i++)
     {   
             if(ciag[i] == znakGrupowania)
             {
                        b = !b;
                        temp[j++] = znakPodzialu;
                        continue;
             }
             
             if(b) temp[j++] = ciag[i];
             else
             {
                   if(ciag[i] != znakOdstepu)
                   {
                        temp[j++] = ciag[i];
                   }
            
                   if(ciag[i] == znakOdstepu && ciag[i + 1] != znakOdstepu)
                   {
                       temp[j++] = znakPodzialu;
                   }
             }
     }
     
     temp.resize(j);   
     
     if(temp[0] != znakPodzialu) temp = znakPodzialu + temp;
     if(temp[temp.length() - 1] != znakPodzialu) temp = temp + znakPodzialu;
     
     ciag = temp;
     
     j = 0;     
     for(int i = 0; i < ciag.length(); i++)
     {
             if(!(ciag[i] == znakPodzialu && ciag[i + 1] == znakPodzialu))
             {
                        temp[j++] = ciag[i];
             }
     }
     
     temp.resize(j);     
          
     polecenie = temp;
}

void CLiniaPolecen::Blad()
{
     
}

W skrócie służy do wczytywania polecen przez użytkownika, dzielenia go na parametry, zwracanie ilosci parametrow, zwracania tych parametrow jako string, int lub double albo porownywanie parametru o okreslonym numerze ze stringiem, intem albo doublem, przy porownywaniu stringow mozna dolozyc opcjonalny parametr bool ktory decyduje o wrazliwosci na wielkosc liter lub o jego braku.

Klasa jest mocno konfigrowalna - można ustawić własny znak odstępu (domyślnie spacja), znak podziału sformatowanego łancucha (domyślnie |), znak grupowania (domyślnie ") lub znak zachęty (domyślnie :).

Mam nadzieje ze komus sie przyda :)

przykład implementacji

#include <cstdlib>
#include <iostream>
#include "CLiniaPolecen.h"

using namespace std;

int main()
{
    CLiniaPolecen LP;
    
    LP.UstawZnakZachety("Wiersz polecen: ");
    float zmienna;
    int zmienna2;
    
    bool wyjdz = false;
    
    while(!wyjdz)
    {
                 LP.Pobierz();
                 
                 if(LP.Porownaj("cin", 0))
                 {
                                      for(int i = 0; i < LP.ZwrocIlosc(); i++)
                                      {
                                              cout << i << " - " << LP.Zwroc(i) << "\n";
                                      }
                                      cout << "\n\n";  
                 }                             
                 
                 if(LP.Porownaj("grupe", 0))
                                         LP.UstawZnakGrupowania(LP.Zwroc(1)[0]);
                 
                 if(LP.Porownaj("cmd", 0))
                                       LP.UstawZnakZachety(LP.Zwroc(1));
                                       
                 if(LP.Porownaj("space", 0))
                                         LP.UstawZnakOdstepu(LP.Zwroc(1)[0]);
                 
                 if(LP.Porownaj("cls", 0)) system("cls");
                 
                 if(LP.Porownaj("sys", 0)) system(LP.Zwroc(1).c_str());
                 
                 if(LP.Porownaj("float", 0))
                 {
                                       if(LP.Porownaj("set", 1)) zmienna = LP.ZwrocDouble(2);
                                       if(LP.Porownaj("get", 1)) cout << zmienna << '\n';
                 }
                 
                 if(LP.Porownaj("int", 0))
                 {
                                       if(LP.Porownaj("set", 1)) zmienna2 = LP.ZwrocInt(2);
                                       if(LP.Porownaj("get", 1)) cout << zmienna2 << '\n';
                 }
                     
                 if(LP.Porownaj("exit", 0)) wyjdz = true;
    }
}

Krytykując mnie ponad wszelkie wyobrażenie chciałbym przypomnieć że jestem początkujący w C++

Pozdrawiam :)

0
class CLiniaPolecen
{
      private:             
              string polecenie;
              string znakZachety;
              char znakOdstepu;
              char znakPodzialu;
              char znakGrupowania;
                                   
              void Formatuj(); // OK!
              void Blad();
             
      public:
             // Glowne
             CLiniaPolecen(); // OK!
             void Pobierz(); // OK!
             
             // Znak zachety
             void UstawZnakZachety(string ciag); // Parametrem powinna byc const-referencja
             string ZwrocZnakZachety(); // Metoda powinna byc const 
             
             // Znak odstepu
             void UstawZnakOdstepu(char c); // 
             char ZwrocZnakOdstepu();  // Metoda powinna byc const 
                         
             // Znak podzialu
             void UstawZnakPodzialu(char c); // OK!
             char ZwrocZnakPodzialu();  // Metoda powinna byc const 
             
             // Znak grupowania
             void UstawZnakGrupowania(char c); // OK!
             char ZwrocZnakGrupowania(); // Metoda powinna byc const 
             
             // Parametry
             int ZwrocIlosc();  // Metoda powinna byc const 
             string Zwroc(int numer); // OK!
             int ZwrocInt(int numer); // OK!
             double ZwrocDouble(int numer); // OK!
              // Metoda powinna byc const, i pierwszym parametrem powinna byc 
             // const-referencja string
             bool Porownaj(string ciag, int numer, bool wrazliwy = false); 
             bool Porownaj(int liczba, int numer);  // Metoda powinna byc const 
             bool Porownaj(double liczba, int numer); // Metoda powinna byc const
};

Napisałem jakie poprawki mozesz dodac(wiekszac dotyczy wydajnosci ale nie tylko):

  1. Masz duzo metod nie-const które powinny byc const/bez tego modyfikatora nie bedziesz mógł wywołac tych metod na obiektach stałych
  2. przekazujesz wartosci przez wartosc tu: string, a powinno byc const string & co zwiekszy wydajnosc gdyz nie przekazujemy całego obiektu lecz tylko jego adres/alias(lecz nie wskaznik bo to zupełnie inna sprawa).

1 użytkowników online, w tym zalogowanych: 0, gości: 1