C++类型转换深度解析:从基础数据类型到字符串,再到基础数据类型的完美转换指南
前言
在 C++ 编程中,我们经常需要在基础数据类型(如 int
、double
、float
、long
、unsigned int
等)与 string
类型之间进行转换。这种转换对于处理用户输入、格式化输出、数据存储等场景至关重要。
本文将详细介绍如何在 C++ 中实现这些转换。
文章目录
- 前言
- 基础数据类型转到 string
- 使用 std::to_string
- 使用 stringstream
- 使用 sprintf
- 使用 iostream
- string 转化为基础数据类型
- 使用 stoi,stod,stof,stol
- 使用 stringstream
- 使用 atof,atoi,atol
- stox 与 atox 的使用区别
- 项目开发中的通用转化形式
- 直接用标准库中的问题
- 通用转化形式示例
- basic_numeric_convertor.h
- basic_numeric_convertor.cpp
- 总结
基础数据类型转到 string
使用 std::to_string
C++11 标准库提供了 std::to_string
函数,它适用于基本数值类型,包括 float
、double
、long
、unsigned int
等。
#include <string>float f = 123.45f;
double d = 123.45;
long l = 123L;
unsigned int ui = 123u;std::string strFloat = std::to_string(f);
std::string strDouble = std::to_string(d);
std::string strLong = std::to_string(l);
std::string strUnsignedInt = std::to_string(ui);
使用 stringstream
stringstream
是处理字符串流的类,可以用来将数值转换为字符串。
#include <sstream>int num = 123;
std::stringstream ss;
ss << num;
std::string str = ss.str();
使用 sprintf
sprintf
函数可以用来将数值格式化为字符串。
#include <cstdio>int num = 123;
char buffer[50];
sprintf(buffer, "%d", num);
std::string str(buffer);
使用 iostream
直接使用 iostream
库中的流操作符重载。
#include <iostream>int num = 123;
std::string str;
std::cout << num;
std::getline(std::cin, str);
string 转化为基础数据类型
使用 stoi,stod,stof,stol
C++11 引入了 stoi
(字符串到整数),stod
(字符串到双精度浮点数),stof
(字符串到单精度浮点数),stol
(字符串到长整数)等函数。
#include <string>std::string str = "123";
int num = std::stoi(str);
double dNum = std::stod(str);
float fNum = std::stof(str);
long lNum = std::stol(str);
使用 stringstream
使用 stringstream
将字符串转换为数值。
#include <sstream>std::string str = "123";
int num;
std::stringstream ss;
ss << str;
ss >> num;
使用 atof,atoi,atol
使用 atof
(字符串到双精度浮点数),atoi
(字符串到整数),atol
(字符串到长整数)等函数。
#include <cstdlib>std::string str = "123";
int num = atoi(str.c_str());
double dNum = atof(str.c_str());
long lNum = atol(str.c_str());
stox 与 atox 的使用区别
atox
和 stox
是C++中用于将字符串转换为基础数据类型的两类函数,但它们属于不同的命名空间,具有不同的特性和使用场景。
我们以 atoi
和 stoi
为例来看看它们的差异。
-
命名空间:
atoi
属于cstdlib
命名空间,是C标准库的一部分。stoi
属于std
命名空间,是C++标准库的一部分。
-
类型安全:
atoi
将字符串转换为int
类型,但它不进行类型检查。如果字符串表示的数超出int
类型的范围,将会导致未定义行为。stoi
将字符串转换为模板指定的类型(如int
、long
、unsigned long
等),如果字符串表示的数超出模板指定类型的范围,stoi
会抛出一个std::out_of_range
异常。
-
异常处理:
- 使用
atoi
时,如果字符串不是有效的整数,atoi
将返回 0,并且不会提供任何错误的信息或异常。这可能使得调试错误变得更加困难。 stoi
在遇到无效输入或数值溢出时会抛出异常,这允许调用者捕获异常并适当地处理错误。
- 使用
-
使用示例:
- 使用
atoi
:#include <cstdlib> const char* str = "123"; int num = atoi(str);
- 使用
stoi
:#include <string> std::string str = "123"; int num = std::stoi(str);
- 使用
-
C++标准:
atoi
是C语言的传统函数,也被C++所兼容。stoi
是C++11标准引入的,是C++语言的一部分,提供了更现代和安全的方法。
-
性能:
- 在某些情况下,
atoi
可能比stoi
稍微快一些,因为它是C语言的函数,没有异常处理的开销。但是,这种差异通常非常小,不足以影响大多数应用程序的选择。
- 在某些情况下,
-
推荐使用:
- 在C++项目中,推荐使用
stoi
或其他C++标准库函数,因为它们提供了更好的类型安全和异常处理机制。
- 在C++项目中,推荐使用
项目开发中的通用转化形式
直接用标准库中的问题
当我们在项目中进行开发时,会发现,直接使用这些标准库中的接口,可能会有各种不足的地方。
比如说:期望将字符串转化为非十进制下的数值;对转化失败进行校验;期望能自己控制转化精度;缓存区溢出考虑;期望能跨平台;能通识性的考虑性能等等问题。
这时候按步照搬的使用这些接口可能就适用了,需用开发者自己去封装和适配接口。
在此,笔者提供一种通用的转化形式,供学习者参考下。
通用转化形式示例
basic_numeric_convertor.h
#ifndef _BASIC_NUMERIC_CONVERTOR_H_
#define _BASIC_NUMERIC_CONVERTOR_H_#include <string>using namespace std;class BasicNumericConvertor final
{
public:enum Format{E, // format as [-]9.9E[+|-]999e, // format as [-]9.9e[+|-]999f, // format as [-]9.9G, // use E or f format, Depends on which way makes the string representation shortestg // use e or f format, Depends on which way makes the string representation shortest};/*** @brief convert int to string* @param[in] n 待转换的整数* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的字符串*/static string numericToString(int n, int base = 10);/*** @brief convert unsigned int to string* @param[in] n 待转换的整数* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的字符串*/static string numericToString(unsigned int n, int base = 10);/*** @brief convert long to string* @param[in] n 待转换的整数* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的字符串*/static string numericToString(long n, int base = 10);/*** @brief convert unsigned long to string* @param[in] n 待转换的整数* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的字符串*/static string numericToString(unsigned long n, int base = 10);/*** @brief convert long long to string* @param[in] n 待转换的整数* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的字符串*/static string numericToString(long long n, int base = 10);/*** @brief convert unsigned long long to string* @param[in] n 待转换的整数* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的字符串*/static string numericToString(unsigned long long n, int base = 10);/*** @brief convert double to string* @param[in] n 待转换的浮点数* @param[in] precision 指定了在转换结果中应包含的小数位数* @param[in] format 指定浮点数的格式化方式(如'f'、'e'、'g'等)* @return 转换后的字符串*/static string numericToString(double n, int precision = 6, Format format = Format::f);/*** @brief convert double to string.(注意:如果有效数字全是0,将会使用科学计数法)* @param[in] n 待转换的浮点数* @param[in] isSuppressTrailingZeros 是否抑制末尾的零* @param[in] precision 指定了在转换结果中应包含的小数位数* @return 转换后的字符串*/static string numericToStringEx(double n, bool isSuppressTrailingZeros, int precision = 6);/*** @brief convert string to short* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 short*/static short stringToShort(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to unsigned short* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 unsigned short*/static unsigned short stringToUShort(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to int* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 int*/static int stringToInt(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to unsigned int* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 unsigned int*/static unsigned int stringToUInt(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to long* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 long*/static long stringToLong(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to unsigned long* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 unsigned long*/static unsigned long stringToULong(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to long long* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 long long*/static long long stringToLongLong(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to unsigned long long* @param[in] str 待转换的字符串* @param[out] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @param[in] base 数字将以 {base} 进制进行转换,如:2,8,10,16* @return 转换后的 unsigned long long*/static unsigned long long stringToULongLong(const string& str, bool* ok = nullptr, int base = 10);/*** @brief convert string to float* @param[in] str 待转换的字符串* @param[in] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @return 转换后的 float*/static float stringToFloat(const string& str, bool* ok = nullptr);/*** @brief convert string to double* @param[in] str 待转换的字符串* @param[in] ok 用于接收转换是否成功的结果。如果你传入了 ok 的地址,当转换成功时,*ok 将会被设置为 true;如果转换失败,则设置为 false* @return 转换后的 double*/static double stringToDouble(const string& str, bool* ok = nullptr);
};#endif // _BASIC_NUMERIC_CONVERTOR_H_
basic_numeric_convertor.cpp
#include "basic_numeric_convertor.h"#include <QtCore/QMap>
#include <QtCore/QString>#include <cassert>static inline string stringFromQString(const QString& str)
{return string(str.toStdWString().c_str());
}string BasicNumericConvertor::numericToString(int n, int base)
{const QString qs = QString::number(n, base);return stringFromQString(qs);
}string BasicNumericConvertor::numericToString(unsigned int n, int base)
{const QString qs = QString::number(n, base);return stringFromQString(qs);
}string BasicNumericConvertor::numericToString(long n, int base)
{const QString qs = QString::number(n, base);return stringFromQString(qs);
}string BasicNumericConvertor::numericToString(unsigned long n, int base)
{const QString qs = QString::number(n, base);return stringFromQString(qs);
}string BasicNumericConvertor::numericToString(long long n, int base)
{const QString qs = QString::number(n, base);return stringFromQString(qs);
}string BasicNumericConvertor::numericToString(unsigned long long n, int base)
{const QString qs = QString::number(n, base);return stringFromQString(qs);
}string BasicNumericConvertor::numericToString(double n, int precision, Format format)
{const QMap<Format, char> fmtMap = {{Format::E, 'E'},{Format::e, 'e'},{Format::f, 'f'},{Format::g, 'g'},{Format::G, 'G'}};const char qf = fmtMap.value(format);int ep = std::numeric_limmits<double>::digits10;const QString qs1 = QString::number(n, qf, ep);int idx = qs1.indexOf('.');if (idx < 0) {return stringFromQString(qs1);}const QString qs2_ = QString::number(n, qf, precision);idx = qs2_.indexOf('.');if (idx < 0) {return stringFromQString(qs2_);}const QString qs2 = qs2_.leftJustified(idx + 1 + ep, '0');int resIndex = idx + 1;const QString subStr1 = qs1.mid(resIndex, precision + 1);if (qs2.indexOf('.') < 0) {resIndex--;}const QString subStr2 = qs2.mid(resIndex, precision + 1);string res = stringFromQString(qs1).mid(0, resIndex + precision);if (subStr2 != subStr1) {res = stringFromQString(qs2).mid(0, resIndex + precision);}return res;
}string BasicNumericConvertor::numericToStringEx(double n, bool isSuppressTrailingZeros, int precision)
{assert(precision >= 0 && precision <= 24);auto toString = [](double n, int precision) {if ((std::Math::abs(n) - 1.0) > 1e-10) {return BasicNumericConvertor::numericToString(n, precision, BasicNumericConvertor::f);}QString qsF = QString::number(n, 'f', precision);const int dotIndex = std::Math::isNegative(n) ? 2 : 1;assert(precision == 0 || precision + dotIndex + 1 == qsF.length());for (int i = 0; i < precision; ++i) {if (qsF.at(dotIndex + i) != '0') {return BasicNumericConvertor::numericToString(n, precision, BasicNumericConvertor::f);}}QString qsE = QString::number(n, 'e', precision);if (qsE.lastIndexOf("+00") > dotIndex) {return stringFromQString(qsF);}int plusIndex = qsE.lastIndexOf('+');if (plusIndex > dotIndex) {int removeLength = (qsE.at(plusIndex + 1) == '0') ? 2 : 1;qsE = qsE.remove(plusIndex, removeLength);return stringFromQString(qsE);}int minusIndex = qsE.lastIndexOf('-');if (minusIndex > dotIndex) {if (qsE.at(minusIndex + 1) == '0') {qsE = qsE.remove(minusIndex + 1, 1);}return stringFromQString(qsE);}assert(false);return BasicNumericConvertor::numericToString(n, precision, BasicNumericConvertor::f)}string numericString = toString(n, precision);if (isSuppressTrailingZeros && precision > 0) {// todo numericString = }return numericString;
}short BasicNumericConvertor::stringToShort(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toShort(ok, base);
}unsigned short BasicNumericConvertor::stringToUShort(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toUShort(ok, base);
}int BasicNumericConvertor::stringToInt(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toInt(ok, base);
}unsigned BasicNumericConvertor::stringToUInt(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toUInt(ok, base);
}long BasicNumericConvertor::stringToLong(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toLong(ok, base);
}unsigned long BasicNumericConvertor::stringToULong(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toULong(ok, base);
}long long BasicNumericConvertor::stringToLongLong(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toLongLong(ok, base);
}unsigned long long BasicNumericConvertor::stringToULongLong(const string& s, bool* ok, int base)
{const QString qs = QString::fromWCharArray(s);return qs.toULongLong(ok, base);
}template<typename T>
static T toFloatPoint(const QString& qs, bool* ok)
{return 0;
}template<>
float toFloatPoint<float>(const QString& qs, bool* ok)
{return qs.toFloat(ok);
}template<>
float toFloatPoint<double>(const QString& qs, bool* ok)
{return qs.toDouble(ok);
}template<typename T, int ep>
static T toFloatPoint(const string& s, bool* ok)
{const QString qs = QString::fromWCharArray(s);const int index = s.find(L("."));if (index == -1) {return toFloatPoint<T>(qs, ok);}int n = (s.length() - index - 1) > ep ? ep : (s.length() - index - 1);string str1 = s.mid(index + 1, static_cast<int>(n));while(n < ep) {str1 += L("0");n++;}T res = toFloatPoint<T>(qs, ok);int maxEp = std::numeric_limits<double>::max_digits10;const string resStr = stringFromQString(QString::munber(res, 'f', maxEp));const string str2 = resStr.mid(index + 1, static_cast<int>(n));if (str1 > str2) {return res + str::pow(0.1, ep);} else if (str1 < str2) {return res - std::pow(0.1, ep);}return res;
}float BasicNumericConvertor::stringToFloat(const string& s, bool* ok)
{const int ep = std::numeric_limits<float>::digits10;return toFloatPoint<float, ep>(s, ok);
}double BasicNumericConvertor::stringToDouble(const string& s, bool* ok)
{const int ep = std::numeric_limits<double>::digits10;return toFloatPoint<double, ep>(s, ok);
}
总结
本文详细介绍了 C++ 中基础数据类型与 string
之间的转换方法。同时,也讨论了转换过程中可能遇到的问题和注意事项,以及提出的一套通用的转换方法。希望这些信息能够帮助 C++ 开发者更好地处理数据类型转换的任务。
大家要是有不懂的地方,欢迎私信交流。
相关文章:

C++类型转换深度解析:从基础数据类型到字符串,再到基础数据类型的完美转换指南
前言 在 C 编程中,我们经常需要在基础数据类型(如 int、double、float、long、unsigned int 等)与 string 类型之间进行转换。这种转换对于处理用户输入、格式化输出、数据存储等场景至关重要。 本文将详细介绍如何在 C 中实现这些转换。 文…...

一文了解:渐进式web应用(PWA),原生应用还香吗?
前端开发是一个充满活力和不断演进的领域,各类技术层出不穷,PWA模式的出现就是想让web移动应用获得原生一样的体验,同时有大幅度降低开发成本,那么它到底能行吗?贝格前端工场带领大家了解一下。 一、什么是渐进式web应…...

SOLIDWORKS学生支持 可访问各种产品资源
你是不是一个热爱设计、追求创新的学生?你是不是在寻找一款能够帮助你实现设计梦想的工具?那么,SolidWorks学生支持是你的首要选择! SOLIDWORKS作为三维CAD设计软件,一直致力于为广大学生提供全方面的支持。无论你是初…...

VCS基本仿真
这里记录三种仿真方式: 第一种是将verilog文件一个一个敲在终端上进行仿真; 第二种是将多个verilog文件的文件路径整理在一个文件中,然后进行仿真; 第三种是利用makefile文件进行仿真; 以8位加法器为例: …...

Hbase中Rowkey的设计方法
Hbase中Rowkey的设计方法 过去对于Rowkey设计方法缺乏理解,最近结合多篇博主的文章,进行了学习。有不少心得体会。总结下来供后续学习和回顾。 一、设计Rowkey的三个原则 1.长度原则:长度不能太长,小于100个字节。可以偏端一些…...

Python基础总结之functools.wraps介绍与应用
Python基础总结之functools.wraps介绍与应用 在Python编程中,装饰器(decorator)是一种非常强大的工具,它允许开发者在不改变函数本身的情况下,动态地增加函数的功能。使用装饰器时,常常会用到 functools.wr…...

UE5基础1-下载安装
目录 一.下载 二.安装 三.安装引擎 四.其他 简介: UE5(Unreal Engine 5)是一款功能极其强大的游戏引擎。 它具有以下显著特点: 先进的图形技术:能够呈现出令人惊叹的逼真视觉效果,包括高逼真的光影、材…...

前端实现获取后端返回的文件流并下载
前端实现获取后端返回的文件流并下载 方法一:使用Axios实现文件流下载优点缺点 方法二:使用封装的Request工具实现文件流下载优点缺点 方法三:直接通过URL跳转下载优点缺点 结论 在前端开发中,有时需要从后端获取文件流࿰…...

Windows下对于Qt中带 / 的路径的处理
在Windows下,如果你想使用操作系统的分隔符显示用户的路径,请使用 toNativeSeparators()。 请看以下代码: void Player::on_playBtn_clicked() {if (this->m_url.isEmpty()) {openMedia();if (this->m_url.isEmpty())return;}qDebug(…...

[leetcode]swap-nodes-in-pairs
. - 力扣(LeetCode) class Solution { public:ListNode* swapPairs(ListNode* head) {ListNode* dummyHead new ListNode(0);dummyHead->next head;ListNode* temp dummyHead;while (temp->next ! nullptr && temp->next->next !…...

国思RDIF.vNext全新低代码快速开发框架平台6.1版本发布(支持vue2、vue3)
1、平台介绍 RDIF.vNext,全新低代码快速开发集成框架平台,给用户和开发者最佳的.Net框架平台方案,为企业快速构建跨平台、企业级的应用提供强大支持。 RDIF.vNext的前身是RDIFramework框架,RDIF(Rapid develop Integrate Framewor…...

中国地市分布图
原文链接https://mp.weixin.qq.com/s?__bizMzUyNzczMTI4Mg&mid2247693904&idx1&snb54884975272eaecb1d0564cafc128d3&chksmfa76a96dcd01207b939b8852a08eea9852eeffa8cc51a3af055dfca5c999e93301237e95901b&token1851596113&langzh_CN#rd...

HCIA11 网络安全之本地 AAA 配置实验
AAA 提供 Authentication(认证)、Authorization(授权)和 Accounting(计费)三种安全功能。 • 认证:验证用户是否可以获得网络访问权。 • 授权:授权用户可以使用哪些服务。 •…...

用Python处理Excel的资源
用Python处理Excel的资源 python-excel 读写Excel文件 openpyxl openpyx文档l 读写Excel2010文件(即xlsx) openpyxl示例: from openpyxl import Workbook wb Workbook()# 获取active worksheet ws wb.active# 给单元格赋值 ws[A1] 4…...

2024年中国移动游戏市场研究报告
来源:点点数据: 近期历史回顾: 面向水泥行业的5G虚拟专网技术要求(2024).pdf 2024年F5G-A绿色万兆全光园区白皮书.pdf 2024年全球废物管理展望报告.pdf 内容管理系统 2024-2025中国羊奶粉市场消费趋势洞察报告.pdf 20…...

JS-12-es6常用知识-async
目录 1. 定义与概述 2. 使用方法 3. 注意事项 4. 应用场景 5. 示例代码 6.总结 async 是 JavaScript(包括 TypeScript)中的一个关键字,用于声明一个函数为异步函数。async其实是一个promise的语法糖,以下是关于 async 的详细…...

使用winscp 通过中转机器(跳板机、堡垒机)密钥远程连接服务器,保姆级别教程
1.winscp下载地址 winscp下载 2.安装自己选择位置 3.连接服务器 到这里,基本就是没有壁垒机的就可直接连接,传递文件 4.配置中转服务器(壁垒机、跳板机) 选择高级选项 配置utf-8的编码格式 配置中转服务器(壁垒机、跳板机) 设置中专机的密码或者私钥 配置私钥...

力扣-1984. 学生分数的最小差值
文章目录 力扣题目工程代码C实现python实现 力扣题目 给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数。另给你一个整数 k 。 从数组中选出任意 k 名学生的分数,使这 k 个分数间 最高分 和 最低分 的 差值 达到 最小化 。…...

激动人心的LayerDiffusion终于可以在ComfyUI中使用了
一、什么是LayerDiffusion 随着Stable Diffusion等散射模型的蓬勃发展,人工智能图形生成进入了一个崭新的阶段。我们可以仅仅通过文字提示,就可以让AI模型为我们生成逼真的图像。但是,目前主流的AI生成模型大多只能生成普通的RGB图像,对生成具有透明通道的图片能力还非常有限。…...

【JVM】finalize() 方法的定义与作用
finalize() 方法的定义与作用 定义 finalize() 方法是 Java 中的一种特殊方法,定义在 java.lang.Object 类中。它在对象被垃圾回收之前由垃圾回收器调用,用于执行清理操作。 方法签名: protected void finalize() throws Throwable作用 …...

这10个前端库,帮我在工作中赢得了不少摸鱼时间!!
文章目录 前言1、dayjs2、 lodash3、 Quill4、 crypto-js5、 viewerjs6、 localforage7、 vconsole8、 uuid9、 copy-text-to-clipboard10、 classnames前言 通过高效的工具提高工作效率,从而有更多的时间来处理其他重要的任务,或者……摸鱼。没错!就是摸鱼。毕竟,提高效率…...

(2024最新)CentOS 7上在线安装MySQL 5.7
在CentOS 7上安装MySQL 5.7并配置允许远程连接,以下是详细步骤: 1. 添加MySQL官方存储库 首先,下载并添加MySQL的官方存储库。默认情况下,添加的存储库可能会包含最新的MySQL版本(如MySQL 8.0),…...

【C++高阶】C++继承学习手册:全面解析继承的各个方面
📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C “ 登神长阶 ” 🤡往期回顾🤡:模板进阶 🌹🌹期待您的关注 🌹🌹 继承 📖1. 继承的概念及定义…...

使用GPT-soVITS再4060下2小时训练声音模型以及处理断句带来的声音模糊问题
B站UP主视频 感谢UP主“白菜工厂1145号员工”的“熟肉”,我这篇笔记就不展示整一个训练和推理流程,重点写的4060该注意的一些事项。如何解决断句模糊的问题,在本篇笔记的最末尾。 相关连接: 原项目github UP主的说明文档 1、训…...

如何对stm32查看IO功能。
有些同学对于别人的开发板的资源,或者IO口,或者串口等资源不知道怎么分配。 方法1、看硬石、野火、正点原子的开发板,看下他们的例子,那个资源用什么。自己多看几个原理图,多看几个视频,做一下笔记。以后依…...

docker构建jdk17镜像
资料参考 参考自黑马教程:10.Docker基础-自定义镜像_哔哩哔哩_bilibili 更多详细语法声明,请参考官网文档:https://docs.docker.com/engine/reference/builder 初步准备 1、下载jdk17包(linux版),我这边版…...
Android Uri转File path路径,Kotlin
Android Uri转File path路径,Kotlin /*** URI转化为file path路径*/private fun getFilePathFromURI(context: Context, contentURI: Uri): String? {val result: String?var cursor: Cursor? nulltry {cursor context.contentResolver.query(contentURI, null…...

iOS界面设计要点:四大模块解析
UI设计不是艺术设计,这限制了我们从设备和现有技术开始设计。因此,熟悉每个平台的设计规则已经成为每个设计师的第一课,也是每个设计师必要的专业知识。 今天小边给您带来了iOS设计规范,希望帮助您快速熟悉iOS平台设计规范&#…...

数字取证技术(Digital Forensics Technology)实验课II
数字取证技术(Digital Forensics Technology)实验课II 本文是我本学期的教学课题目,不包含任何博客知识分享,无关的读者可忽略; 实验练习题 (♞思考):请对工作邮件进行签名;“problem3_1.txt"里存储的是由John Doe撰写的真实的邮件,而"problem3_2.txt"里存储的…...

Redis缓存的使用
1.缓存穿透 描述:查询数据在redis不存在,请求打到数据库 解决方法: 缓存空值 当出现Redis查不到数据,数据库也查不到数据的情况,我们就把这个key保存到Redis中,设置value"null",并设…...