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"};
}