平时在进行类型转换时,特别是从字符串转换为数字时,都要考虑安全问题。既不能默许,又应该及时发现处理,于是,自己写了安全的封装。
正文
static std::string char_to_string(const char* buff, const size_t buff_size) {
std::string str(buff, buff_size);
return str;
}
static std::string string_sprintf(const char* format, ...) {
va_list args;
va_start(args, format);
std::string buff = string_vsnprintf(format, args);
va_end(args);
return buff;
}
static std::string string_vsnprintf(const std::string& format, va_list args) {
// try first
int32_t try_size = 512;
char try_buff[try_size];
memset(try_buff, 0, try_size);
std::string res;
int32_t size_needed = std::vsnprintf(try_buff, try_size, format.c_str(), args);
if (size_needed < try_size) {
res = try_buff;
} else {
// try again
char buff_needed[size_needed+1];
memset(buff_needed, 0, size_needed+1);
int32_t size = std::vsnprintf(buff_needed, size_needed+1, format.c_str(), args);
if (size >= 0) {
res = std::string(buff_needed);
} else {
res = std::string("");
}
}
return res;
}
static void _string_append(const std::string& file, const char* format, va_list ap) {
assert(!file.empty());
FILE* fp = nullptr;
if (file == "stdout") {
fp = stdout;
} else if (file == "stderr") {
fp = stderr;
} else {
fp = fopen(file.c_str(), "a");
}
if (fp != nullptr) {
std::vfprintf(fp, format, ap);
if ((file != "stdout") && (file != "stderr")){
fclose(fp);
fp = nullptr;
}
}
}
static void string_append(const std::string& file, const char* format, ...) {
assert(!file.empty());
va_list ap;
va_start(ap, format);
_string_append(file, format, ap);
va_end(ap);
}
static int32_t bool_to_int(const bool b) {
int32_t i = 0;
if (b == true) {
i = 1;
}
return i;
}
static bool int_to_bool(const int32_t i, bool zero_as_false) {
bool res = false;
if (zero_as_false && (i != 0)) {
res = true;
} else if ((!zero_as_false) && (i == 0)) {
res = true;
}
// MISRA C++ 2008: 6-6-5
return res;
}
static int32_t safe_stoi(const std::string& str) {
int32_t res = 0;
try {
res = std::stoi(str);
} catch (std::out_of_range& e) {
res = 0;
} catch (std::invalid_argument& e) {
res = 0;
}
// MISRA C++ 2008: 6-6-5
return res;
}
static int64_t safe_stoll(const std::string& str) {
int64_t res = 0;
try {
res = std::stoll(str);
} catch (std::out_of_range& e) {
res = 0;
} catch (std::invalid_argument& e) {
res = 0;
}
// MISRA C++ 2008: 6-6-5
return res;
}
static double safe_stod(const std::string& str) {
double res = 0.0;
try {
res = std::stod(str);
} catch (std::out_of_range& e) {
res = 0.0;
} catch (std::invalid_argument& e) {
res = 0.0;
}
// MISRA C++ 2008: 6-6-5
return res;
}
static std::vector<double> safe_stodv(const std::string& s) {
std::vector<double> res;
int left_i = s.find('[');
int right_i = s.find(']');
if (left_i >= 0 && right_i >= 0 && left_i < right_i) {
std::string sub = s.substr(left_i + 1, right_i - left_i - 1);
std::vector<std::string> str_vec = string_split(sub, ",");
for (auto v : str_vec) {
res.push_back(safe_stod(v));
}
}
return res;
}