C++11:便利的工具

news/2024/9/22 22:19:37/

目录

  • 1 处理日期和时间的chrono库
    • 1.1 记录时长的duration
    • 1.2 表示时间点的time point
    • 1.3 获取系统时钟的clocks
  • 2 数值类型和字符串的相互转换
  • 3 宽窄字符转换

1 处理日期和时间的chrono库

1.1 记录时长的duration

duration表示一段时间间隔,用来记录时间长度,可以表示几秒、几分钟或者几个小时的时间间隔。duration的原型如下:

template<class Rep,class Period = std::ratio<1,1>
> class duration;

第一个模板参数Rep是一个数值类型,表示时钟数的类型;第二个模板参数是一个默认模板参数std::ratio,表示时钟周期,它的原型如下:

template<std::intmax_t Num,std::intmax_t Denom = 1
>class ratio;

它表示每个时钟周期的秒数,其中第一个模板参数Num代表分子,Denom代表分母,分母默认为1,因此,ratio代表的是一个分子除以分母的分数值,比如ratio<2>代表一个时钟周期是两秒, ratio<60>代表一分钟, ratio<60 * 60>代表一个小时, ratio<60 * 60 * 24>代表一天。而ratio<1,1000>代表的则是1/1000秒,即一毫秒,ratio<1, 1 000 000>代表一微秒,ratio<1,1 000 000 000>代表一纳秒。为了方便使用,标准库定义了一些常用的时间间隔,如时、分、秒、毫秒、微秒和纳秒,在 chrono命名空间下,它们的定义如下:

typedef duration <Rep, ratio<3600,1>> hours;
typedef duration <Rep, ratio<60,1>> minutes;
typedef duration <Rep, ratio<1,1>> seconds;
typedef duration <Rep, ratio<1,1000>> milliseconds;
typedef duration <Rep,ratio<1,1000000>> microseconds;
typedef duration <Rep,ratio<1,1000000000>> nanoseconds;

通过定义这些常用的时间间隔类型,我们能方便地使用它们,比如线程的休眠:

std::this_thread::sleep_for(std::chrono::seconds(3));	//休眠3秒
std::this_thread::sleep_for(std::chrono::milliseconds(100));	//休眠100毫秒

chrono还提供了获取时间间隔的时钟周期数的方法count(),它的基本用法如下:

#include <chrono>
#include <iostream>
int main ()
{std::chrono::milliseconds ms{3};	//3毫秒std::chrono::microseconds us = 2*ms;	//6000微秒std::chrono::duration<double, std::ratio<1, 30>> hz30 {3.5}; //30Hz clock using fractional ticksstd: :cout <<"3 ms duration has " << ms.count () << " ticks \n"<<"6000 us duration has " << us.count ( ) << " ticks\n";
}

输出如下:
3 ms duration has 3 ticks
6000 us duration has 6000 ticks
时间间隔之间可以做运算,计算两端时间间隔的差值的示例如下:

std::chrono::minutes t1(10);
std::chrono::seconds t2(60) ;
std::chrono::seconds t3 = t1 - t2;
std::cout<< t3.count () <<" second" << std: :endl;

其中,t1代表10分钟、t2代表60秒,t3则是t1减去t2,也就是600-60=540秒。通过调用t3的count输出差值为540个时钟周期,因为t3的时钟周期为1秒,所以t3表示的时间间隔为540秒。

1.2 表示时间点的time point

time_point 表示一个时间点,用来获取从它的clock 的纪元开始所经过的duration(比如,可能是1970.1.1以来的时间间隔)和当前的时间,可以做一些时间的比较和算术运算,可以和ctime库结合起来显示时间。time_point必须用clock 来计时。time_point有一个函数time_from_eproch()用来获得1970年1月1日到 time_point时间经过的duration。下面是计算当前时间距离1970年1月1日有多少天的示例。

#include <iostream>
#include <ratio>
#include <chrono>int main()
{using namespace std:: chrono;typedef duration<int, std:: ratio<60*60*24>> days_type;time_point<system_clock, days_type> today =time_point_cast<days_type>(system_clock::now());std::cout << today.time_since_epoch().count() << " days since epoch" <<std:: endl;return 0;
}

time_point还支持一些算术运算,比如两个time_point的差值时钟周期数,还可以和duration相加减。要注意不同clock 的time_point是不能进行算术运算的。下面的例子输出前一天和后一天的日期。

#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>int main()
{using namespace std::chrono;system_clock::time_point now = system_clock::now();std::time_t last = system_clock::to_time_t(now - hours(24));std::time_t next = system_clock::to_time_t(now + hours(24));std::cout << "One day ago, the time was "<< std::put time(std::localtime(&last),"%F %T") << '\n ';std::cout << "Next day, the time is "<< std::put_time(std::localtime(&next)"%F %T") << '\n ';
}

输出如下:
one day ago, the time was 2014-3-2622:38: 27
Next day, the time is 2014-3-2822:38:27
需要注意的是,上面的代码在vs2013下能编译通过,但在GCC下是不能编译通过的,因为GCC 还没有支持std::put_time。

1.3 获取系统时钟的clocks

clocks表示当前的系统时钟,内部有time_point、duration、Rep、Period等信息,主要用来获取当前时间,以及实现time_t和 time _point的相互转换。clocks包含如下3种时钟:
system_clock: 代表真实世界的挂钟时间,具体时间值依赖于系统。system_clock 保证提供的时间值是一个可读时间。
steady_clock: 不能被“调整”的时钟,并不一定代表真实世界的挂钟时间。保证先后调用now()得到的时间值是不会递减的。
high_resolution_clock: 高精度时钟,实际上是system_clock或者steady_clock 的别名。可以通过now()来获取当前时间点,代码如下:

#include <iostream>
#include <chrono>
int main ()
{std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now();std::cout<<"Hello world\n" ;std::chrono::system_clock::time_point t2 = std::chrono::system_clock::now();std::cout<< (t2-t1).count()<<"tick count"<<std::endl;
}

输出如下:
Hello world
97tick count
system_clock和std::put_time配合起来使用可以格式化日期的输出。下面的例子是将当前时间格式化输出。

#include <chrono>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main ()
{auto t = chrono::system_clock::to_time_t(std::chrono::system_clock::now());cout<< std::put_time(std::localtime(&t),"%Y-%m-%d %x")<<endl;cout<< std::put_time(std:: localtime(&t),"%Y-%m-%d %H.%M.%S")<<endl;return 0;
}

输出结果如下:
2014-3-27 22:11: 49
2014-3-27 22.11.49

2 数值类型和字符串的相互转换

C++11提供了to_string方法,可以方便地将各种数值类型转换为字符串类型:
std::string to_string( int value ) ;
std::string to_string( long value ) ;
std::string to_string( long long value ) ;
std::string to_string( unsigned value );
std::string to_string( unsigned long value );
std::string to_string( unsigned long long value );
std::string to_string( float value );
std::string to_string( double value );
std::string to_string( long double value );

std::wstring to_wstring( int value );
std::wstring to_wstring( long value );
std::wstring to_wstring( long long value );
std::wstring to_wstring( unsigned value );
std::wstring to_wstring( unsigned long value ) ;
std::wstring to_wstring( unsigned long long value );
std::wstring to_wstring( float value ) ;
std::wstring to_wstring( double value );
std::wstring to_wstring( long double value );

C++11还提供了字符串转换为整型和浮点型的方法:
atoi:将字符串转换为int类型。
atol:将字符串转换为long类型。
atoll:将字符串转换为long long类型。
atof:将字符串转换为浮点型。

#include <iostream>
#include <string>int main(void)
{double f = 1.53;std::string f_str = std::to_string(f);std::cout << f_str << std::endl;double f1 = 4.125;std::wstring f_str1 = std::to_wstring(f1);std::wcout << f_str1 << std::endl;const char* str1 = "10";const char* str2 = "3.1415926";const char* str3 = "31337 with words";const char* str4 = "words and 2";int num1 = std::atoi(str1);int num2 = std::atoi(str2);int num3 = std::atoi(str3);int num4 = std::atoi(str4);double f2 = std::atof(str2);std::cout << "std::atoi(\"" << str1 << "\") is " << num1 << '\n'; std::cout << "std::atoi(\"" << str2 << "\") is " << num2 << '\n'; std::cout << "std::atoi(\"" << str3 << "\") is " << num3 << '\n'; std::cout << "std::atoi(\"" << str4 << "\") is " << num4 << '\n'; std::cout << "std::atoi(\"" << str2 << "\") is " << f2 << std::endl; system("pause");return 0;
}

输出结果如下:
std::atoi(“10”) is 10
std::atoi(“3.14159”) is 3
std::atof (“31337 with words”) is 31337
std::atoi ( “words and 2”) is 0
如果需要转换的字符串前面部分不是数字,会返回0,上面的str4转换后返回0; 如果字符串的前面部分有空格和含数字,转换时会忽略空格并获得前面部分的数字。

3 宽窄字符转换

C++11增加了unicode字面量的支持,可以通过L来定义宽字符:

std::wstring str = L”中国人";	//定义unicode字符串

将宽字符串转换为窄字符串需要用到codecvt库中的std::wstring_convert。std::wstring_convert需要借助unicode转换器:

#include <iostream>
#include <string>
#include <codecvt>int main(void)
{std::wstring str = L"我是中国人yzb";std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>> converter(new std::codecvt<wchar_t, char, std::mbstate_t>("CHS"));std::string narrowStr = converter.to_bytes(str);std::wstring wstr = converter.from_bytes(narrowStr);std::cout << narrowStr << std::endl;std::wcout.imbue(std::locale("chs"));  //初始化cout为中文输出std::wcout << wstr << std::endl;system("pause");return 0;
}

输出结果如下:
中国人
中国人


http://www.ppmy.cn/news/40347.html

相关文章

【Rust基础】语法知识

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人学习Rust语言整理的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于b站的Rust中文社群线上学习室和菜鸟教程进行的&#xff0c;每个知识…

个人-计算机操作系统第三章

一、章节习题 1、在分时系统中&#xff0c;进程调度经常采用______算法。 A 先来先服务 B 最大优先权 C 时间片轮转 D 随机 2、进程调度有各种各样的算法&#xff0c;如果算法处理不当&#xff0c;就会出现____现象。 A 颠簸&#xff08;抖动&a…

什么是水审计

1.1 水审计 水审计即落实水量平衡表&#xff0c;由国际水协专家组团队协助供水企业构建水量平衡表的过程可以帮助供水企业的管理人员认识NRW的大小、来源和成本。 用水量平衡表来计算漏损的每一个构成要素&#xff0c;从而查明漏失的原因。这将决定政策的改变和经营方法的优先…

MLOps : 机器学习运维

文章目录MLOps : 机器学习运维产生背景MLOpos 做了什么事情MLOps : 机器学习运维 产生背景 因为存在如下的背景&#xff0c;所以才有了 MLOps 的需求 第一&#xff0c;跨团队协作难度大。机器学习项目生命周期中涉及业务、数据、算法、研发、运维等多团队&#xff0c;团队间缺…

Win10怎么取消开机密码?这样做就可以!

集美们&#xff0c;我每次开电脑都要输入密码&#xff0c;感觉太麻烦了&#xff0c;想把开机密码取消掉&#xff0c;应该怎么做呀&#xff1f;感谢回答&#xff01;】 在Windows 10操作系统中&#xff0c;用户可以设置开机密码来保护计算机的安全性。然而&#xff0c;有时候用…

洛谷P8799 [蓝桥杯 2022 国 B] 齿轮 C语言/C++

[蓝桥杯 2022 国 B] 齿轮 题目描述 这天&#xff0c;小明在组装齿轮。 他一共有 nnn 个齿轮&#xff0c;第 iii 个齿轮的半径为 rir_{i}ri​, 他需要把这 nnn 个齿轮按一定顺序从左到右组装起来&#xff0c;这样最左边的齿轮转起来之后&#xff0c;可以传递到最右边的齿轮&a…

ChatGPT大规模封号+停止注册?最火概念会凉吗?

一、背景 这个周末&#xff0c;先是意大利暂时封杀ChatGPT&#xff0c;限制OpenAI处理本国用户信息。 接着&#xff0c;据韩国媒体报道&#xff0c;三星导入ChatGPT不到20天&#xff0c;便曝出机密资料外泄&#xff08;涉及半导体设备测量资料、产品良率等内容&#xff0c;已…

面试手撕堆排序

堆排序代码如下&#xff08;注释见下&#xff09;&#xff1a; 首先将待排序的数组构造成一个大根堆&#xff0c;此时&#xff0c;整个数组的最大值就是堆结构的堆顶 将堆顶的数与末尾的数交换&#xff0c;此时&#xff0c;末尾的数为最大值&#xff0c;剩余待排序数组个数为n…