1
votes

I want to be able to throw an exception in case the user has not typed the month names correctly... So I came uip with the idea of storing the names in a static array in a class called Data...

Here is the static array I am talking about: string Data::nomes_meses[12]{"Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"}; You can see it in the file data.cpp.

The code which is bugging my application is the following:

int mes{};
auto itr = find(Data::nomes_meses, Data::nomes_meses + 12, date_parts[1]);

if (itr == end(Data::nomes_meses))
{
    throw("Você deve informar uma data válida");
}

mes = distance(Data::nomes_meses, itr);

If we try, as for instance "Jan" in the find function we can see the exception being thrown terminate called after throwing an instance of 'char const*' ...

auto itr = find(Data::nomes_meses, Data::nomes_meses + 12, "Jan");

Alhough it will work just fine for some months, for instance: Fev, Mar, Abr, Jun, Ago...

Does someone out there know what the heck is this issue I am facing??

data.h

#ifndef DOMINIOS_H_INCLUDED
#define DOMINIOS_H_INCLUDED

#include <stdexcept>
#include <vector>    
class Data
{
private:
    string data;
    void validar(string);

    static const int ANO_MAX_VALIDO = 9999;
    static const int ANO_MIN_VALIDO = 2000;
    bool ehAnoBissexto(int);

public:
    static string nomes_meses[12];
    inline string getData() { return data; }
    void setData(string data);

    Data(string data);
    Data(const Data &src);
    Data(Data &&src);
    ~Data();
};

#endif // DOMINIOS_H_INCLUDED

data.cpp

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sstream>
#include <regex>

#include "data.h"    
string Data::nomes_meses[12]{"Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"};

void Data::validar(string data)
{
    stringstream ss, ss_dia;

    string date_parts[3]{};
    regex str_expr("^(?:(\\d\\d)\\/([A-Z][a-z]{2})\\/(\\d{4})|([a-z]{3})\\/(\\d\\d)\\/(\\d{4}))$");
    if (!regex_match(data, str_expr))
    {
        throw("Informe uma data válida");
    }

    string s = data;
    string delimiter = "/";

    size_t pos = 0;
    string token;
    int i{0};

    while ((pos = s.find(delimiter)) != string::npos)
    {
        token = s.substr(0, pos);
        date_parts[i] = token;
        cout << token << endl;
        s.erase(0, pos + delimiter.length());
        ++i;
    }

    date_parts[i] = s;
    int ano{};
    ss << date_parts[2];
    ss >> ano;

    int mes{};
    auto itr = find(Data::nomes_meses, Data::nomes_meses + 12, date_parts[1]);

    if (itr == end(Data::nomes_meses))
    {
        throw("Você deve informar uma data válida");
    }

    mes = distance(Data::nomes_meses, itr);

    int dia{};
    ss_dia << date_parts[0];
    ss_dia >> dia;
    if (ano > ANO_MAX_VALIDO ||
        ano < ANO_MIN_VALIDO)
        throw("Informe uma data válida");
    if (mes < 1 || mes > 12)
        throw("Você deve informar um mês válido");
    if (dia < 1 || dia > 31)
        throw("Você deve informar um dia válido");

    if (mes == 2)
    {
        if (ehAnoBissexto(ano))
            if (!dia <= 29)
                throw("Informe uma data válida");
            else if (!dia <= 28)
                throw("Informe uma data válida");
    }

    if ((mes == 4 || mes == 6 ||
         mes == 9 || mes == 11) &&
        (!dia <= 30))
        throw("Informe uma data válida");
}

bool Data::ehAnoBissexto(int ano)
{
    return (((ano % 4 == 0) &&
             (ano % 100 != 0)) ||
            (ano % 400 == 0));
}

void Data::setData(string data)
{
    this->data = data;
}

Data::Data(string data) : data{data}
{
    validar(data);
}
Data::~Data() {}

main.cpp

#include <iostream>
#include <ctime>
#include <vector>
#include "data.h"


using namespace std;

vector<string> Cidade::cidades;
vector<Codigo *> Codigo::codigos;
void display_cities()
{
     vector<string> cities = Cidade::getCidades();
     cout << cities.size() << endl;
     for (size_t i = 0; i < cities.size(); i++)
     {
          cout << cities[i] << endl;
     }
}

int main()
{
     Data newDate2{"12/Fev/2022"};
     Data newDate3{"12/Mar/2022"};
     Data newDate4{"12/Abr/2022"};
     Data newDate5{"12/Mai/2022"};
     Data newDate1{"12/Jan/2022"};
     Data newDate6{"12/Jun/2022"};
     Data newDate7{"15/Jul/2022"};
     Data newDate8{"15/Ago/2022"};
     Data newDate9{"28/Set/2022"};
     Data newDate10{"15/Out/2022"};
     Data newDate11{"28/Nov/2022"};
     Data newDate12{"28/Dez/2022"};
}
That's far from a minimal reproducible example as you're required to post here!πάντα ῥεῖ
You can test everything out there only checking the descriptionBreno
If we try, as for instance "Jan" in the find function we can see the exception being thrown terminate called after throwing an instance of 'char const*' ... auto itr = find(Data::nomes_meses, Data::nomes_meses + 12, "Jan"); Alhough it will work just fine for some months, for instance: Fev, Mar, Abr, Jun, Ago... Does someone out there know what the heck is this issue I am facing??Breno
No clear error messages, tons of completely unrelated code?? Are you serious? Go edit your question please!πάντα ῥεῖ
terminate called after throwing an instance of 'char const*' that's the only exception I can seeBreno