CPP06 1.0
読み取り中…
検索中…
一致する文字列を見つけられません
ScalarConverter.cpp
[詳解]
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* ScalarConverter.cpp :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: kamitsui <kamitsui@student.42tokyo.jp> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2025/07/22 14:23:39 by kamitsui #+# #+# */
9/* Updated: 2025/08/16 00:03:20 by kamitsui ### ########.fr */
10/* */
11/* ************************************************************************** */
12
18#include "ScalarConverter.hpp"
19#include <cmath> // std::isnan, std::isinf, std::isfinite を使うために必要
20#include <cstdlib>
21#include <cstring>
22#include <iomanip>
23#include <iostream>
24#include <limits>
25#include <sstream> // For std::stringstream
26#include <string> // For std::string
27
28// Private constructor definitions to prevent instantiation.
29ScalarConverter::ScalarConverter() {}
30ScalarConverter::ScalarConverter(const ScalarConverter &src) { (void)src; }
31ScalarConverter &ScalarConverter::operator=(const ScalarConverter &rhs) {
32 (void)rhs;
33 return *this;
34}
35ScalarConverter::~ScalarConverter() {}
36
42static bool isPseudoLiteral(const std::string &literal) {
43 const std::string pseudoLiterals[] = {"nan", "nanf", "+inf", "+inff", "-inf", "-inff"};
44 for (size_t i = 0; i < sizeof(pseudoLiterals) / sizeof(std::string); ++i) {
45 if (literal == pseudoLiterals[i]) {
46 return true;
47 }
48 }
49 return false;
50}
51
56static void printPseudoLiterals(const std::string &literal) {
57 std::cout << "char: impossible" << std::endl;
58 std::cout << "int: impossible" << std::endl;
59 if (literal == "nan" || literal == "nanf") {
60 std::cout << "float: nanf" << std::endl;
61 std::cout << "double: nan" << std::endl;
62 } else if (literal == "+inf" || literal == "+inff" || literal == "inf" || literal == "inff") {
63 std::cout << "float: +inff" << std::endl;
64 std::cout << "double: +inf" << std::endl;
65 } else if (literal == "-inf" || literal == "-inff") {
66 std::cout << "float: -inff" << std::endl;
67 std::cout << "double: -inf" << std::endl;
68 }
69}
70
75// * @param literal Original input string. Used to determine decimal point display.
76// static void printConversions(double d, const std::string &literal) {
77static void printConversions(double d) {
78 // char conversion
79 std::cout << "char: ";
82 std::cout << "impossible" << std::endl;
83 } else if (!std::isprint(static_cast<char>(d))) {
84 std::cout << "Non displayable" << std::endl;
85 } else {
86 std::cout << "'" << static_cast<char>(d) << "'" << std::endl;
87 }
88
89 // int conversion
90 std::cout << "int: ";
91 if (std::isnan(d) || std::isinf(d) || d < std::numeric_limits<int>::min() || d > std::numeric_limits<int>::max()) {
92 std::cout << "impossible" << std::endl;
93 } else {
95 }
96
97 // --- float conversion ---
98 std::cout << "float: ";
99 float f = static_cast<float>(d);
100 std::stringstream ss_float;
101 ss_float << f; // First convert numerical values to strings
102 std::string float_str = ss_float.str();
103
104 // If the string contains neither a decimal point nor an ‘e’ (exponent), “.0” is added
105 if (float_str.find('.') == std::string::npos && float_str.find('e') == std::string::npos && std::isfinite(f)) {
106 float_str += ".0";
107 }
108 std::cout << float_str << "f" << std::endl;
109
110 // --- double conversion ---
111 std::cout << "double: ";
112 std::stringstream ss_double;
113 ss_double << d;
114 std::string double_str = ss_double.str();
115
116 if (double_str.find('.') == std::string::npos && double_str.find('e') == std::string::npos && std::isfinite(d)) {
117 double_str += ".0";
118 }
119 std::cout << double_str << std::endl;
120
121 // -------------- Before refactor 2th ---------------
122
123 // // --- float conversion ---
124 // std::cout << "float: ";
125 // float f = static_cast<float>(d);
126 // // Add “.0” only if the number is finite (not inf/nan) and the decimal portion is 0
127 // if (std::isfinite(f) && f == static_cast<long>(f)) {
128 // std::cout << f << ".0f" << std::endl;
129 // } else {
130 // std::cout << f << "f" << std::endl;
131 // }
132
133 // // --- double conversion ---
134 // std::cout << "double: ";
135 // // Add “.0” only if the number is finite (not inf/nan) and the decimal portion is 0
136 // if (std::isfinite(d) && d == static_cast<long>(d)) {
137 // std::cout << d << ".0" << std::endl;
138 // } else {
139 // std::cout << d << std::endl;
140 // }
141
142 // -------------- Before refactor 1th ---------------
143
144 // Revert to std::cout's default floating point number format
145 // std::cout.unsetf(std::ios_base::floatfield);
146
147 // float conversion
148 // float f = static_cast<float>(d);
149 // std::cout << "float: " << f;
150 // // If there is no decimal part, add .0 if there is no decimal point or 'f' in the input
151 // if (f - static_cast<int>(f) == 0 && literal.find('.') == std::string::npos &&
152 // literal.find('f') == std::string::npos) {
153 // std::cout << ".0";
154 // }
155 // // If the input has a decimal point and the decimal portion is 0
156 // else if (f - static_cast<int>(f) == 0 && literal.find('.') != std::string::npos) {
157 // std::cout << ".0";
158 // }
159 // std::cout << "f" << std::endl;
160
161 // // double display
162 // std::cout << "double: " << d;
163 // if (d - static_cast<int>(d) == 0 && literal.find('.') == std::string::npos &&
164 // literal.find('f') == std::string::npos) {
165 // std::cout << ".0";
166 // } else if (d - static_cast<int>(d) == 0 && literal.find('.') != std::string::npos) {
167 // std::cout << ".0";
168 // }
169 // std::cout << std::endl;
170}
171
178 if (literal.empty()) {
179 std::cout << "Error: Empty string provided." << std::endl;
180 return;
181 }
182
183 // Handle pseudo-literals
184 if (isPseudoLiteral(literal)) {
185 printPseudoLiterals(literal);
186 return;
187 }
188
189 // Handle char literals
190 if (literal.length() == 3 && literal[0] == '\'' && literal[2] == '\'') {
191 char c = literal[1];
192 // printConversions(static_cast<double>(c), literal);
193 printConversions(static_cast<double>(c));
194 return;
195 }
196
197 // Try to parse as a number
198 char *endptr;
199 double d = strtod(literal.c_str(), &endptr);
200
201 // Validate parse result
202 if (endptr == literal.c_str() || (*endptr != '\0' && (*endptr != 'f' || *(endptr + 1) != '\0'))) {
203 std::cout << "char: impossible" << std::endl;
204 std::cout << "int: impossible" << std::endl;
205 std::cout << "float: impossible" << std::endl;
206 std::cout << "double: impossible" << std::endl;
207 return;
208 }
209
210 // Print conversions from the parsed number
211 printConversions(d);
212}
Contains the declaration of the ScalarConverter static class.
T c_str(T... args)
A static class to convert string literals to scalar types.
static void convert(const std::string &literal)
The main conversion method.
T empty(T... args)
T endl(T... args)
T find(T... args)
T isfinite(T... args)
T isinf(T... args)
T isnan(T... args)
T length(T... args)
T str(T... args)