Files
cpp09/ex00/BitcoinExchange/BitcoinExchange.cpp
2026-04-24 13:22:01 +02:00

202 lines
4.6 KiB
C++

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* BitcoinExchange.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: aortigos <aortigos@student.42malaga.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/04/23 19:54:20 by aortigos #+# #+# */
/* Updated: 2026/04/23 19:54:20 by aortigos ### ########.fr */
/* */
/* ************************************************************************** */
#include "BitcoinExchange.hpp"
using std::cout;
using std::endl;
//////////////////
// Constructors //
//////////////////
BitcoinExchange::BitcoinExchange()
{
// std::cout << "BitcoinExchange default constructor called" << std::endl;
}
BitcoinExchange::BitcoinExchange(const BitcoinExchange &other)
{
*this = other;
// std::cout << "BitcoinExchange copy constructor called" << std::endl;
}
BitcoinExchange& BitcoinExchange::operator=(const BitcoinExchange &other)
{
if (this != &other)
{
this->data = other.data;
}
// std::cout << "BitcoinExchange copy assignment operator called" << std::endl;
return (*this);
}
BitcoinExchange::~BitcoinExchange()
{
// std::cout << "BitcoinExchange destructor called" << std::endl;
}
void BitcoinExchange::readDatabase(std::ifstream &db)
{
std::string line;
std::getline(db, line);
if (line != "date,exchange_rate")
throw std::exception();
size_t pos;
std::string date;
std::string price;
while (std::getline(db, line))
{
pos = line.find(',');
if (pos == std::string::npos)
continue ;
date = line.substr(0, pos);
price = line.substr(pos + 1);
this->data[date] = std::strtod(price.c_str(), NULL);
}
}
void BitcoinExchange::execute(std::ifstream &db)
{
std::string line;
std::getline(db, line);
if (line != "date | value")
throw std::exception();
size_t pos;
std::string date;
std::string value;
while (std::getline(db, line))
{
pos = line.find('|');
if (pos == std::string::npos)
{
cout << "Error: bad input => " << line << endl;
continue;
}
date = line.substr(0, pos);
value = line.substr(pos + 1);
while (date.size() && date[date.size() - 1] == ' ')
date.erase(date.size() - 1);
while (value.size() && value[0] == ' ')
value.erase(0, 1);
if (!validateAll(date, value))
continue ;
std::map<std::string, double>::iterator it = this->data.lower_bound(date);
if (it == this->data.begin() && it->first != date)
{
cout << "Error: bad input => " << date << endl;
continue;
}
if (it->first != date)
it--;
cout << date << " => " << value << " = " << it->second * std::strtod(value.c_str(), NULL) << endl;
}
}
bool BitcoinExchange::validateAll(const std::string &date, const std::string &value)
{
int res;
res = validateValue(value);
if (!validateDate(date))
{
cout << "Error: bad input => " << date << endl;
return (false);
}
else if (res == 1)
{
cout << "Error: not a number." << endl;
return (false);
}
else if (res == 2)
{
cout << "Error: not a positive number." << endl;
return (false);
}
else if (res == 3)
{
cout << "Error: too large a number." << endl;
return (false);
}
return (true);
}
bool BitcoinExchange::validateDate(const std::string &date)
{
int maxDay = 31;
int year;
int month;
int day;
bool bisiesto;
if (date.length() != 10 || date[4] != '-' || date[7] != '-')
return (false);
for (int i = 0; i < 10; i++)
{
if (i == 4 || i == 7)
continue;
if (!isdigit(date[i]))
return (false);
}
year = std::atoi(date.substr(0, 4).c_str());
month = std::atoi(date.substr(5, 2).c_str());
day = std::atoi(date.substr(8, 2).c_str());
bisiesto = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
if (year < 2008)
return (false);
if (month < 1 || month > 12)
return (false);
if (month == 4 || month == 6 || month == 9 || month == 11)
maxDay = 30;
else if (month == 2)
{
if (bisiesto)
maxDay = 29;
else
maxDay = 28;
}
if (day < 1 || day > maxDay)
return (false);
return (true);
}
int BitcoinExchange::validateValue(const std::string &value)
{
char *endptr;
double val = std::strtod(value.c_str(), &endptr);
if (*endptr != '\0')
return (1);
if (val < 0)
return (2);
else if (val > 1000)
return (3);
return (0);
}