Something went wrong. Try again.
Java--'s type casting projects.intra.42.fr/projects/cpp-module-06
Something went wrong. Try again.
7.5 kB · 265 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266#include <ScalarConverter.hpp>#include <cctype>#include <cstddef>#include <iostream>#include <cstdlib>#include <limits>#include <iomanip>
enum Type { CHAR, INT, FLOAT, DOUBLE, INVALID};
static Type getType(const std::string& input) { if (input.length() == 1 && !std::isdigit(static_cast<unsigned char>(input[0]))) return CHAR;
if (input == "nanf" || input == "+inff" || input == "-inff") return FLOAT;
if (input == "nan" || input == "+inf" || input == "-inf" || input == "inf") return DOUBLE;
const size_t length = input.length(); if (length > 1 && (input[length - 1] == 'f' || input[length - 1] == 'F')) { char* end; std::strtod(input.c_str(), &end); if (end == input.c_str() + length - 1) return FLOAT; }
char* end; errno = 0; std::strtol(input.c_str(), &end, 10); if (end == input.c_str() + length && errno != ERANGE) return INT;
std::strtod(input.c_str(), &end); if (end == input.c_str() + length) return DOUBLE;
return INVALID;}
// ─── Parsing ────────────────────────────────────────────────────────────────
static char parseChar(const std::string& input) { return input[0];}
static long parseLong(const std::string& input) { return static_cast<long>(std::strtol(input.c_str(), NULL, 10));}
static float parseFloat(const std::string& input) { if (input == "nanf") return std::numeric_limits<float>::quiet_NaN();
if (input == "+inff") return std::numeric_limits<float>::infinity();
if (input == "-inff") return -std::numeric_limits<float>::infinity();
return static_cast<float>(std::strtod(input.c_str(), NULL));}
static double parseDouble(const std::string& input) { if (input == "nan") return std::numeric_limits<double>::quiet_NaN();
if (input == "+inf") return std::numeric_limits<double>::infinity();
if (input == "-inf") return -std::numeric_limits<double>::infinity();
if (input == "inf") return std::numeric_limits<double>::infinity();
return static_cast<double>(std::strtod(input.c_str(), NULL));}
// ─── Printing ───────────────────────────────────────────────────────────────
static bool isNan(const float f) { return f != f;}
static bool isNan(const double d) { return d != d;}
static bool isInf(const float f) { return f == std::numeric_limits<float>::infinity() || f == -std::numeric_limits<float>::infinity();}
static bool isInf(const double d) { return d == std::numeric_limits<double>::infinity() || d == -std::numeric_limits<double>::infinity();}
static void printChar(const char c) { if (std::isprint(static_cast<unsigned char>(c))) std::cout << "'" << c << "'"; else std::cout << "Non displayable";}
static void printChar(const long l) { if (l < std::numeric_limits<char>::min() || l > std::numeric_limits<char>::max()) std::cout << "impossible"; else printChar(static_cast<char>(l));}
static void printChar(const float f) { if (isNan(f) || isInf(f) || f < std::numeric_limits<char>::min() || f > std::numeric_limits<char>::max()) std::cout << "impossible"; else printChar(static_cast<char>(f));}
static void printChar(const double d) { if (isNan(d) || isInf(d) || d < std::numeric_limits<char>::min() || d > std::numeric_limits<char>::max()) std::cout << "impossible"; else printChar(static_cast<char>(d));}
static void printInt(const char c) { std::cout << static_cast<int>(c);}
static void printInt(const long l) { if (l < std::numeric_limits<int>::min() || l > std::numeric_limits<int>::max()) std::cout << "impossible"; else std::cout << static_cast<int>(l);}
static void printInt(const float f) { if (isNan(f) || isInf(f) || f < static_cast<float>(std::numeric_limits<int>::min()) || f > static_cast<float>(std::numeric_limits<int>::max())) std::cout << "impossible"; else std::cout << static_cast<int>(f);}
static void printInt(const double d) { if (isNan(d) || isInf(d) || d < std::numeric_limits<int>::min() || d > std::numeric_limits<int>::max()) std::cout << "impossible"; else std::cout << static_cast<int>(d);}
static void printFloat(const char c) { std::cout << static_cast<float>(c) << 'f';}
static void printFloat(const long l) { if (static_cast<float>(l) > std::numeric_limits<float>::max() || static_cast<float>(l) < -std::numeric_limits<float>::max()) std::cout << "impossible"; else std::cout << static_cast<float>(l) << 'f';}
static void printFloat(const float f) { if (isNan(f)) std::cout << "nanf"; else if (isInf(f)) std::cout << (f > 0 ? "+inff" : "-inff"); else std::cout << f << 'f';}
static void printFloat(const double d) { if (isNan(d)) std::cout << "nanf"; else if (isInf(d)) std::cout << (d > 0 ? "+inff" : "-inff"); else if (d > std::numeric_limits<float>::max() || d < -std::numeric_limits<float>::max()) std::cout << "impossible"; else std::cout << static_cast<float>(d) << 'f';}
static void printDouble(const char c) { std::cout << static_cast<double>(c);}
static void printDouble(const long l) { std::cout << static_cast<double>(l);}
static void printDouble(const float f) { std::cout << static_cast<double>(f);}
static void printDouble(const double d) { if (isNan(d)) std::cout << "nan"; else if (isInf(d)) std::cout << (d > 0 ? "+inf" : "-inf"); else std::cout << d;}
// ─── Conversion ─────────────────────────────────────────────────────────────
void ScalarConverter::convert(const std::string& input) { std::cout << std::setprecision(1) << std::fixed; const Type type = getType(input);
std::cout << "type : "; switch (type) { case CHAR: std::cout << "CHAR"; break; case INT: std::cout << "INT"; break; case FLOAT: std::cout << "FLOAT"; break; case DOUBLE: std::cout << "DOUBLE"; break; case INVALID: std::cout << "INVALID"; break; } std::cout << std::endl;
std::cout << "char : "; switch (type) { case CHAR: printChar(parseChar(input)); break; case INT: printChar(parseLong(input)); break; case FLOAT: printChar(parseFloat(input)); break; case DOUBLE: printChar(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl;
std::cout << "int : "; switch (type) { case CHAR: printInt(parseChar(input)); break; case INT: printInt(parseLong(input)); break; case FLOAT: printInt(parseFloat(input)); break; case DOUBLE: printInt(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl;
std::cout << "float : "; switch (type) { case CHAR: printFloat(parseChar(input)); break; case INT: printFloat(parseLong(input)); break; case FLOAT: printFloat(parseFloat(input)); break; case DOUBLE: printFloat(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl;
std::cout << "double: "; switch (type) { case CHAR: printDouble(parseChar(input)); break; case INT: printDouble(parseLong(input)); break; case FLOAT: printDouble(parseFloat(input)); break; case DOUBLE: printDouble(parseDouble(input)); break; case INVALID: std::cout << "impossible"; break; } std::cout << std::endl;}