郑州做网站推广价格,在win10下建设网站,做网站需要写代码吗,海口网站建设方面前言
在 C 编程中#xff0c;我们经常需要在基础数据类型#xff08;如 int、double、float、long、unsigned int 等#xff09;与 string 类型之间进行转换。这种转换对于处理用户输入、格式化输出、数据存储等场景至关重要。
本文将详细介绍如何在 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,atolstox 与 atox 的使用区别 项目开发中的通用转化形式直接用标准库中的问题通用转化形式示例basic_numeric_convertor.hbasic_numeric_convertor.cpp 总结 基础数据类型转到 string
使用 std::to_string
C11 标准库提供了 std::to_string 函数它适用于基本数值类型包括 float、double、long、unsigned int 等。
#include stringfloat 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 sstreamint num 123;
std::stringstream ss;
ss num;
std::string str ss.str();使用 sprintf
sprintf 函数可以用来将数值格式化为字符串。
#include cstdioint num 123;
char buffer[50];
sprintf(buffer, %d, num);
std::string str(buffer);使用 iostream
直接使用 iostream 库中的流操作符重载。
#include iostreamint num 123;
std::string str;
std::cout num;
std::getline(std::cin, str);string 转化为基础数据类型
使用 stoi,stod,stof,stol
C11 引入了 stoi字符串到整数stod字符串到双精度浮点数stof字符串到单精度浮点数stol字符串到长整数等函数。
#include stringstd::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 sstreamstd::string str 123;
int num;
std::stringstream ss;
ss str;
ss num;使用 atof,atoi,atol
使用 atof字符串到双精度浮点数atoi字符串到整数atol字符串到长整数等函数。
#include cstdlibstd::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 是C11标准引入的是C语言的一部分提供了更现代和安全的方法。 性能: 在某些情况下atoi 可能比 stoi 稍微快一些因为它是C语言的函数没有异常处理的开销。但是这种差异通常非常小不足以影响大多数应用程序的选择。 推荐使用: 在C项目中推荐使用 stoi 或其他C标准库函数因为它们提供了更好的类型安全和异常处理机制。
项目开发中的通用转化形式
直接用标准库中的问题
当我们在项目中进行开发时会发现直接使用这些标准库中的接口可能会有各种不足的地方。
比如说期望将字符串转化为非十进制下的数值对转化失败进行校验期望能自己控制转化精度缓存区溢出考虑期望能跨平台能通识性的考虑性能等等问题。
这时候按步照搬的使用这些接口可能就适用了需用开发者自己去封装和适配接口。
在此笔者提供一种通用的转化形式供学习者参考下。
通用转化形式示例
basic_numeric_convertor.h
#ifndef _BASIC_NUMERIC_CONVERTOR_H_
#define _BASIC_NUMERIC_CONVERTOR_H_#include stringusing 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} 进制进行转换如28,10,16* return 转换后的字符串*/static string numericToString(int n, int base 10);/*** brief convert unsigned int to string* param[in] n 待转换的整数* param[in] base 数字将以 {base} 进制进行转换如28,10,16* return 转换后的字符串*/static string numericToString(unsigned int n, int base 10);/*** brief convert long to string* param[in] n 待转换的整数* param[in] base 数字将以 {base} 进制进行转换如28,10,16* return 转换后的字符串*/static string numericToString(long n, int base 10);/*** brief convert unsigned long to string* param[in] n 待转换的整数* param[in] base 数字将以 {base} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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} 进制进行转换如28,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 cassertstatic 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 QMapFormat, 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_limmitsdouble::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);
}templatetypename T
static T toFloatPoint(const QString qs, bool* ok)
{return 0;
}template
float toFloatPointfloat(const QString qs, bool* ok)
{return qs.toFloat(ok);
}template
float toFloatPointdouble(const QString qs, bool* ok)
{return qs.toDouble(ok);
}templatetypename 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 toFloatPointT(qs, ok);}int n (s.length() - index - 1) ep ? ep : (s.length() - index - 1);string str1 s.mid(index 1, static_castint(n));while(n ep) {str1 L(0);n;}T res toFloatPointT(qs, ok);int maxEp std::numeric_limitsdouble::max_digits10;const string resStr stringFromQString(QString::munber(res, f, maxEp));const string str2 resStr.mid(index 1, static_castint(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_limitsfloat::digits10;return toFloatPointfloat, ep(s, ok);
}double BasicNumericConvertor::stringToDouble(const string s, bool* ok)
{const int ep std::numeric_limitsdouble::digits10;return toFloatPointdouble, ep(s, ok);
}总结
本文详细介绍了 C 中基础数据类型与 string 之间的转换方法。同时也讨论了转换过程中可能遇到的问题和注意事项以及提出的一套通用的转换方法。希望这些信息能够帮助 C 开发者更好地处理数据类型转换的任务。
大家要是有不懂的地方欢迎私信交流。