• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Tytuły mają taką samą nazwę.

Object Storage Arubacloud
0 głosów
105 wizyt
pytanie zadane 1 października 2018 w C i C++ przez PelikanFix16 Użytkownik (950 p.)

Tworzę prosty menager zadań w konsoli za pomocą c++ w ramach nauki.

Po włączeniu programu i wpisaniu "create new Task", następnie po wpisaniu "show" wyświetlany jest tytuł "Task" lecz kiedy ponowie komende "create new Task1" i ponownie wpisze "show" poprzedni tytuł zmienia nazwę na "Task1".

main.cpp

#include "TaskDrawer.h"
#include "Task.h"
#include <iostream>
#include <vector>
#include <regex>



int main() {

   
   std::string in;
   std::vector<ITaskManager*> vecDraw;
    

    std::regex wz("create new (.*)");
    std::smatch match;

   while(true){
    std::getline(std::cin,in);

        if(in == "ex"){
            std::cout << "Exit" << std::endl;
            return 0;
        }

        if(std::regex_search(in,match,wz)){
            std::string title = match[1] ;
            Task* tempTa = new Task;
            tempTa->changeTitle(title.c_str());
            ITaskManager* taD = new TaskDrawer;
            taD->setTask(tempTa);
            vecDraw.push_back(taD);
            std::cout << &(vecDraw[vecDraw.size()-1]) << std::endl;
            std::cout << tempTa << std::endl;
        }

        if(in == "show"){
            for(int i=0;i<vecDraw.size();i++){
                ITaskManager* taks = vecDraw[i];
                Task* ta = taks->getTask();
                std::cout << ta->getTitle() << std::endl;

            }

        }



   }

    return 0;
}


ITaskManager.h

#pragma once
#include "Task.h"

class ITaskManager{

    protected:
        Task* _task;
    public:
        virtual void setTask(Task* task) {_task = task;};
        virtual void drawTaskTable() =0;
        virtual Task* getTask() {return _task;} ;



};

Task.h

#pragma once
#include <vector>
#include <iostream>
class Task {


    private:
        const char* _title;
        std::vector<char*> _tasks;

    public:
        const char* getTitle();
        void changeTitle(const char* title);
        void addTask(char* task);
        void deleteTask(unsigned int position);
        const std::vector<char*>* getTasks();
        void changeTask(char* task,unsigned int position);
        const char* getSingleTask(unsigned int position);



};

Task.cpp

#include "Task.h"


void Task::changeTitle(const char* title) {

    _title = title;
}
const char* Task::getTitle() {

    if(_title == 0)
        throw std::invalid_argument("Title is empty");

    return _title;
}
void Task::addTask(char* task) {


    _tasks.push_back(task);

}

const std::vector<char*>* Task::getTasks() {

    return const_cast<const std::vector<char*>*>(&_tasks);

}
void Task::deleteTask(unsigned int position) {

   if(position >= _tasks.size())
        throw std::invalid_argument("Position in vector no avilable");

    std::vector<char*>::iterator it = _tasks.begin();
    std::advance(it,position);
    _tasks.erase(it);

}

void Task::changeTask(char* task,unsigned int position) {

    if(position >= _tasks.size())
        throw std::invalid_argument("Posiiton in vector no available");

    _tasks.at(position) = task;

}

const char* Task::getSingleTask(unsigned int position) {

    if(position >= _tasks.size())
        throw std::invalid_argument("Position in vector no avilable");

    return const_cast<const char*>((_tasks[position]));
    

}

TaskDrawer.h

#pragma once
#include "ITaskManager.h"
#include <iostream>
#include <cstring>
#include <stdio.h>
class TaskDrawer:public ITaskManager {



    private:
        unsigned int _tLeng;

    private:
        inline unsigned int textLenght(char* text){return strlen(text);};
        const char* DrawTitle(const char* title);
        const char* DrawTask(char* task,int pos);
        const char* DrawEnd();

    public:
        virtual void drawTaskTable();




};

TaskDrawer.cpp

#include "TaskDrawer.h"

void TaskDrawer::drawTaskTable(){


  //  unsigned int lengTitle = this->textLenght("test");

   // std::cout << std::string(_lengCol,'-') << std::endl;

    const char* title = this->DrawTitle(this->_task->getTitle());
    _tLeng = this->textLenght(const_cast<char*>(title));

    std::cout << title << std::endl;
    const std::vector<char*>* v = this->_task->getTasks();
    for(int i=0;i<(*v).size();i++) {
        std::cout << this->DrawTask((*v)[i],i) << std::endl;    
    }
    std::cout << this->DrawEnd() << std::endl;
}

const char* TaskDrawer::DrawTitle(const char* title) {

    const std::vector<char*>* vec = this->_task->getTasks();

    unsigned int longestTask = 0;

    for(int i=0;i<(*vec).size();i++){
        unsigned int te = this->textLenght((*vec)[i]);
        if(longestTask < te){
            longestTask = te;
        }
    }

    const char* t1 = std::string(longestTask+(this->textLenght(const_cast<char*>(title))%2),'-').c_str();
    const char* t2 = std::string(longestTask-1,'-').c_str();
    std::string buf(" ");
    buf.append(t1);
    buf.append(title);
    buf.append(t2);
    buf.append("-");
    return buf.c_str();

}

const char* TaskDrawer::DrawTask(char* task,int pos) {

    unsigned int leng = this->textLenght(task);

    unsigned int cal1 = ((_tLeng - leng)/2);

    const char* t1 = std::string(cal1-1,' ').c_str();
    const char* t2 = std::string((cal1)-(leng%2),' ').c_str();
    std::string buf("|");
    buf.append(std::to_string(pos));
    buf.append(t1);
    buf.append(task);
    buf.append(t2);
    buf.append("|");


    return buf.c_str();

}

const char* TaskDrawer::DrawEnd() {

    std::string buf(" ");
    buf.append(std::string(_tLeng-1,'-'));
    return buf.c_str();
}

Makefile


all: a.out
	echo "Build Done"

a.out:main.o Task.o TaskDrawer.o
	g++ main.o Task.o TaskDrawer.o -o TaskManager 

main.o: main.cpp
	g++ -c -Wall main.cpp

Task.o: Task.cpp Task.h 
	g++ -c -Wall Task.cpp
TaskDrawer.o: TaskDrawer.cpp TaskDrawer.h ITaskManager.h 
	g++ -c -Wall TaskDrawer.cpp


clean:
	rm -f *.out *.o

 

komentarz 1 października 2018 przez gakowalski Gaduła (3,080 p.)
Jak masz takie zestawy z dużą ilością plików to łatwiej Tobie i łatwiej nam byłoby, gdybyś wrzucił swój projekt do jakiegoś publicznego repozytorium git i dał nam link. Albo skompresuj całość w jakiś ZIP czy coś.

1 odpowiedź

+1 głos
odpowiedź 1 października 2018 przez adrian17 Ekspert (344,860 p.)
    const char* t1 = std::string(longestTask+(this->textLenght(const_cast<char*>(title))%2),'-').c_str();
    const char* t2 = std::string(longestTask-1,'-').c_str();
    std::string buf(" ");
    buf.append(t1);
    buf.append(title);
    buf.append(t2);
    buf.append("-");
    return buf.c_str();

c_str() zwraca wskaźnik do wewnętrznego bufora stringa. Gdy std::string zniknie, Twój wskaźnik będzie wskazywał na smietnik; widzę tu sporo undefined behavior.

const char* TaskDrawer::DrawEnd() {
 
    std::string buf(" ");
    buf.append(std::string(_tLeng-1,'-'));
    return buf.c_str();
}

Analogicznie.

Najlepiej, gdybyś w ogóle nie używał char* (tylko std::string).

Z bocznych uwag:

const std::vector<char*>* Task::getTasks() {
    return const_cast<const std::vector<char*>*>(&_tasks);
}

Nie trzeba const_cast do konwersji nie-const wskaźnika na wskaźnik na const. A ogólnie lepiej i czytelniej by było, gdyby użyć referencje.

Podobne pytania

+1 głos
2 odpowiedzi 543 wizyt
0 głosów
1 odpowiedź 188 wizyt
0 głosów
3 odpowiedzi 287 wizyt

92,580 zapytań

141,432 odpowiedzi

319,664 komentarzy

61,965 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...