C++进制、类型转换 及 std::string、std::stringstream、std::bitset 常用方法

248 阅读10分钟

.CPP进制、类型转换如有疑问可留言沟通交流Ⅰ. CPP 进制、类型转换:^{如有疑问可留言沟通交流}

C++进制转换除了求余、求商之外还可以通过st::string和std::stringstream来实现,至于二进制的运算可以由std::bitset来实现。

进制、类型转换 常用方法:

// C++ 进制、类型转换常用方法
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 );
int         stoi ( const std::string& str, std::size_t* pos = nullptr, int base = 10 );
long        stol ( const std::string& str, std::size_t* pos = nullptr, int base = 10 );
long long   stoll( const std::string& str, std::size_t* pos = nullptr, int base = 10 );
float       stof ( const std::string& str, std::size_t* pos = nullptr );
double      stod ( const std::string& str, std::size_t* pos = nullptr );
long double stold( const std::string& str, std::size_t* pos = nullptr );
【#include <string>】 https://en.cppreference.com/w/cpp/string/basic_string/to_string

int ivalue = 8; 
std::string svalue = ""; 
std::stringstream ss; // 字符串流
ss << std::hex << ivalue; 
// [std::dec, std::hex, std::oct](https://en.cppreference.com/w/cpp/io/manip/hex)
ss >> svalue; 
ss.str(""); // 清空缓存 
ss.clear(); // 清除标志位
【#include <sstream>】 https://en.cppreference.com/w/cpp/io/basic_stringstream

int ivalue = 8; 
std::string svalue = "00111100"; 
std::bitset<N> bitivalue(ivalue); // int >> bitset<N> 
std::bitset<N> bitsvalue(svalue); // string >> bitset<N> 
bitivalue<<=2; // 左移2位 << 
bitsvalue>>=5; // 右移5位 << 
unsigned long ivalue = bitivalue.to_ulong(); // bitset<N> >> unsigned long 
std::string   svalue = bitsvalue.to_string();// bitset<N> >> std::string
【#include <bitset>】 https://en.cppreference.com/w/cpp/utility/bitset

下面调试了 C++ 进制、类型转换方法(实操):


std::cout<< "------------------------------------------------------------【C++ int】\n";
int decvalue = 99999; // 默认十进制
int binvalue = 0b111; // 二进制以 0b 开头
int octvalue = 07777; // 八进制以 0  开头
int hexvalue = 0xfff; // 16进制以 0x 开头
std::cout<< decvalue++ << "-"<< binvalue++ << "-"<< octvalue++ << "-"<< hexvalue++ << "\n";
std::cout<< decvalue << "-"<< binvalue << "-"<< octvalue << "-"<< hexvalue << "\n";           

std::cout<< "------------------------------------------------------------【C++ <string>】\n";
int         avalueint = 666;
std::string avluestr = std::to_string(avalueint);         // int    >> string
std::string bvluestr = "111";
int         bvalueint = std::stoi(bvluestr);              // string >> int(dec)
int         bvaluebin = std::stoi(bvluestr, nullptr, 2);  // string >> int(bin)
int         bvalueoct = std::stoi(bvluestr, nullptr, 8);  // string >> int(oct)
int         bvaluehex = std::stoi(bvluestr, nullptr, 16); // string >> int(hex)
std::cout<< avalueint << "-\""<< avluestr << "\n";  
std::cout<< bvluestr << "\"-"<< bvalueint << "-"<< bvaluebin << "-"<< bvalueoct << "-"<< bvaluehex << "\n";     
/* reference
int         stoi ( const std::string& str, std::size_t* pos = nullptr, int base = 10 );
long        stol ( const std::string& str, std::size_t* pos = nullptr, int base = 10 );
long long   stoll( const std::string& str, std::size_t* pos = nullptr, int base = 10 );
float       stof ( const std::string& str, std::size_t* pos = nullptr );
double      stod ( const std::string& str, std::size_t* pos = nullptr );
long double stold( const std::string& str, std::size_t* pos = nullptr );
index https://en.cppreference.com/w/cpp/string/basic_string/to_string
*/

std::cout<< "------------------------------------------------------------【C++ <sstream>】\n";
int ivalue = 8;
std::string svalue = "";
std::stringstream ss;
// 十进制整数 >> 十六进制字符串
ss << std::hex << "5a1f05";
ss << std::hex << ivalue;
ss >> svalue;
ss.str(""); // 清空缓存
ss.clear(); // 清除标志位
std::cout<<"十进制 >> 16进制 "<< ivalue << " - " << svalue <<"\n";
std::transform(svalue.begin(),svalue.end(), svalue.begin(), ::toupper);// 字母转大写
// https://en.cppreference.com/w/cpp/algorithm/transform
std::cout<<"十进制 >> 16进制 "<< ivalue << " - " << svalue <<"\n";
// 十进制整数 >> 字符串
ss << std::dec << ivalue;
ss >> svalue;
ss.str(""); // 清空缓存
ss.clear(); // 清除标志位
std::cout<<"十进制 >> 十进制 "<< ivalue << " - " << svalue <<"\n";
// 十进制整数 >> 八进制字符串
ss << std::oct << ivalue;
ss >> svalue;
ss.str(""); // 清空缓存
ss.clear(); // 清除标志位
std::cout<<"十进制 >> 八进制 "<< ivalue << " - " << svalue <<"\n";
// 十进制整数 >> 二进制字符串
ss << std::bitset<32>(ivalue);
ss >> svalue;
ss.str(""); // 清空缓存
ss.clear(); // 清除标志位
std::cout<<"十进制 >> 二进制 "<< ivalue << " - " << svalue <<"\n";

std::cout<< "------------------------------------------------------------【C++ <bitset>】\n";
int decnum = 7;
std::string strnumbin = "00111100";
std::string strnumhex = "A5D3F";
std::bitset<20> bitnumdec(decnum);                            // int         >> bitset<N>
std::bitset<20> bitnumstrbin(strnumbin);                      // string(bin) >> bitset<N>
std::bitset<20> bitnumstrhex(std::stoi(strnumhex,nullptr,16));// string(hex) >> bitset<N>

bitnumdec<<=1; // 左移 << 
// index https://zh.cppreference.com/w/cpp/utility/bitset

unsigned long bit2intnum = bitnumdec.to_ulong(); // bitset<N> >> unsigned long
std::string   bit2strnum = bitnumdec.to_string();// bitset<N> >> string(bin)

stringstream sss;                                // bitset<N> >> string(hex)
std::string  bit2strhex = "";
sss << std::hex << stoi( bitnumdec.to_string(), nullptr, 2); 
sss >> bit2strhex;
sss.str(""); // 清空缓存
sss.clear(); // 清除标志位
std::transform(bit2strhex.begin(),bit2strhex.end(), bit2strhex.begin(), ::toupper);// 字母转大写

std::cout<< decnum << "-" << bitnumdec <<"+" << strnumbin <<"-"<< bitnumstrbin << "-"<< bitnumstrhex << "\n"; 
std::cout<< bitnumdec << "-" << bit2intnum << "-" << bit2strnum << "-" <<  bit2strhex << "\n";
        

运行结果如下

------------------------------------------------------------【C++ int99999-7-4095-4095 
100000-8-4096-4096 
------------------------------------------------------------【C++ <string>】 
666-"666 111"-111-7-73-273 
------------------------------------------------------------【C++ <sstream>】 
十进制 >> 16进制 8 - 5a1f058 
十进制 >> 16进制 8 - 5A1F058 
十进制 >> 十进制 8 - 8 
十进制 >> 八进制 8 - 10 
十进制 >> 二进制 8 - 00000000000000000000000000001000 
------------------------------------------------------------【C++ <bitset>】 
7-00000000000000001110+00111100-00000000000000111100-10100101110100111111 
00000000000000001110-14-00000000000000001110-E

.std::string常用方法如有疑问可留言沟通交流Ⅱ. std::string 常用方法:^{如有疑问可留言沟通交流}

std::string 是在标准库 <string>(注意不是 C 语言中的 <string.h> 库)中提供的一个类,本质上是 std::basic_string<char> 的别称。以下是string常用方法:

std::string s;

std::string::size_type s.size();          // 返回 string 的长度
std::string::size_type s.length();

std::string::size_type s.find(str);       // 查找字符串中 某 字符/字符串 第一次出现的位置 
std::string::size_type s.find(str, pos);  // 查找字符串中 某 字符/字符串 在 pos(含)之后第一次出现的位置 
// 如果没有找到,则返回 std::string::npos

std::string substr(pos, len);             // 从 pos 位置开始截取最多 len 个字符组成的字符串
// 如果从 pos 开始的后缀长度不足 len 则只截取这个后缀

std::string s.insert(index, count, 'c');  // 在 index 处连续插入 count 次字符 'c' 
std::string s.insert(index, "str")        // 在 index 处插入字符串 "str"

std::string s.erase(index,count);         // 删除字符串 index 位置开始(含)的 count 个字符
std::string s.erase(index);               // 删除 index 位置及以后的所有字符

std::string s.replace(pos, count, str);   // 将从 pos 位置开始 count 个字符的子串替换为 str 
std::string s.replace(first, last, str);  // 将以 first 开始(含)、last 结束(不含)的子串替换为 str,其中 first 和 last 均为迭代器。#include <string>】https://en.cppreference.com/w/cpp/string/basic_string

在 C 语言里,也有很多字符串的函数,但是它们的参数都是 char 指针类型的,为了方便使用,string 有两个成员函数能够将自己转换为 char 指针——data()/c_str()(它们几乎是一样的,但最好使用 c_str(),因为 c_str() 保证末尾有空字符,而 data() 则不保证)
参考 string - OI Wiki (oi-wiki.org)

虽然 int 和 char 可以互相转换,依据 ASII码 实现简单的判别或转换。
但对于单个字符而言,有如下些许常用的professional的方法:

int isalnum(int c);   // 检查字符是否为字母或数字
int isalpha(int c);   // 检查字符是否为字母
int islower(int c);   // 检查字符是否为小写
int isupper(int c);   // 检查字符是否为大写字符
int isdigit(int c);   // 检查字符是否为数字
int isxdigit(int c);  // 检查字符是为十六进制字符
int iscntrl(int c);   // 检查字符是否为控制字符
int isgraph(int c);   // 检查字符是否为图形字符
int isspace(int c);   // 检查字符是否为空白间隔字符
int isblank(int c);   // 检查字符是否为空白字符
int isprint(int c);   // 检查字符是否为打印字符
int ispunct(int c);   // 检查字符是否为标点符
int tolower(int c);   // 转换字符为小写
int toupper(int c);   // 转换字符为大写#include <cctype>】https://en.cppreference.com/w/cpp/header/cctype
// C++标准库 `<cctype>` 原作为 `<ctype.h>` 存在于 C 标准库

字符串是一种容器,可以直接调用 std::sort 对若干字符串进行排序。以下是字符串常用方法:

std::transform(svalue.begin(),svalue.end(), svalue.begin(), ::tolower);// 字母转小写
std::transform(svalue.begin(),svalue.end(), svalue.begin(), ::toupper);// 字母转大写#include <algorithm>】https://zh.cppreference.com/w/cpp/algorithm/transform       // 字符变换
std::vector<int> v {3, 1, -4, 1, 5, 9};
std::vector<int>::iterator result = std::min_element(v.begin(), v.end()); // 容器中的最小值
std::vector<int>::iterator result = std::min_element(v.begin(), v.end(), [](int a, int b){ return std::abs(a) > std::abs(b); });
【#include <algorithm>】https://zh.cppreference.com/w/cpp/algorithm/min_element     // 查找最小值
std::vector<int>::iterator result = std::max_element(v.begin(), v.end()); // 容器中的最大值
std::vector<int>::iterator result = std::max_element(v.begin(), v.end(), [](int a, int b){ return std::abs(a) < std::abs(b); });
【#include <algorithm>】https://zh.cppreference.com/w/cpp/algorithm/max_element     // 查找最大值
int count = std::count(v.cbegin(), v.cend(), int target); // 计算容器内中 target 出现的个数
// 由 lambda 表达式计算能被 4 整除的元素个数
int count = std::count_if(v.begin(), v.end(), [](int i) { return i % 4 == 0; }); 
【#include <algorithm>】https://en.cppreference.com/w/cpp/algorithm/count           // 容器计数
std::sort(v.begin(), v.end());
std::sort(v.begin(), v.end(), [](int a, int b){ return a > b; });
【#include <algorithm>】https://en.cppreference.com/w/cpp/algorithm/sort            // 容器排序

有关容器的具体用法可以参考 C++常用标准库容器算法

.std::stringstream常用方法如有疑问可留言沟通交流Ⅲ. std::stringstream 常用方法:^{如有疑问可留言沟通交流}

std::stringstream ss;
ss << std::hex << "5a1f05";
ss.str(""); // 清空缓存
ss.clear(); // 清除标志位#include <sstream>】https://en.cppreference.com/w/cpp/io/basic_stringstream

.std::bitset常用方法如有疑问可留言沟通交流Ⅳ. std::bitset常用方法:^{如有疑问可留言沟通交流}

std::bitset 是标准库中的一个存储 0/1 的大小不可变容器。严格来讲,它并不属于 STL。由于内存地址是按字节即 byte 寻址,而非比特 bit,一个 bool 类型的变量,虽然只能表示 0/1, 但是也占了 1 byte 的内存。std::bitset 就是通过固定的优化,使得一个字节的八个比特能分别储存 8 位的 0/1。其常用方法如下:

// 构造函数
std::bitset(); // 每一位都是 false
std::bitset(unsigned long val); // 整数
std::bitset(const string& str); // 值为 01 字符串

operator<<
operator<<=   // 二进制左移
operator>>  
operator>>=   // 二进制右移
operator==    // 比较其内容
operator&=    // 二进制与
operator|=    // 二进制或
operator^=    // 二进制异或
operator~     // 二进制非
operator[]    // 访问指定的位

bool x.all();                      // 检查所有位是否全为 true 
bool x.any();                      // 检查存在被设为 true 的位
bool x.none();                     // 检查没有被设为 true 的位
std::size_t x.count();             // 返回设置为 true 的位的数量
std::size_t x.size();              // 返回x的位数

std::bitset& x.set();              // 将所有位设置为 true
std::bitset& x.set(pos, value);    // 将 pos 设置为 value
std::bitset& x.reset();            // 将所有位设置为 false
std::bitset& x.reset(pos);         // 将 pos 设置为 false
std::bitset& x.flip();             // 翻转所有位的值
std::bitset& x.flip(pos);          // 翻转 pos 的值

std::string x.to_string('0', '1'); // 转换为字符串表示 (对应值为 false 的位,值为 true 的位)
unsigned long x.to_ulong();        // 转换为整数表示
unsigned long long x.to_ullong();  // 转换为整数表示#include <bitset>】https://en.cppreference.com/w/cpp/utility/bitset

std::bitset 相对应的是 std::vector 的一个特化 std::vector<bool> (可以理解为节省空间的动态 bitset),其储存方式同 std::bitset 一样,区别在于后者支持动态开空间,std::bitset 则和一般的静态数组一样,是在编译时就开好了的。然而,bitset 有一些好用的库函数,不仅方便,而且有时可以避免使用 for 循环而没有实质的速度优化。因此,一般不使用 std::vector<bool>
参考 bitset - (oi-wiki.org)

此外,由 GNU Compiler Collection (GCC) 提供支持的位操作:

auto x = 0ULL; // 无符号整数 (unsigned long long)
auto y = x;    // 无符号整数 (unsigned long long)

__builtin_popcount(x);
__builtin_popcountl(x);
__builtin_popcountll(x);  // 对应二进制中1的个数
__builtin_ctz(x);
__builtin_ctzl(x);
__builtin_ctzll(x);       // 二进制下x末尾0的个数 (x=0 时结果未定义)
__builtin_clz(x);
__builtin_clzl(x);
__builtin_clzll(x);       // 二进制下x前导0的个数 (x=0 时结果未定义)
【-】https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html          // 编译器内置方法

对于无符号整数类型(即 unsigned char 、 unsigned short 、 unsigned int 、 unsigned long 、 unsigned long long 或扩展无符号整数类型)自 C++20 起支持如下位操作方法:

auto x = 0ULL; // 无符号整数 (unsigned long long)
auto y = x;    // 无符号整数 (unsigned long long)

int std::popcount(x);
【#include <bit>】https://en.cppreference.com/w/cpp/numeric/popcount       // 对应二进制中 1 的个数
int std::countl_zero(x); // 从最高位(“左”)起连续为 0 的位的数量#include <bit>】https://en.cppreference.com/w/cpp/numeric/countl_zero
int std::countl_one(x); // 从最高位(“左”)起连续为 1 的位的数量#include <bit>】https://en.cppreference.com/w/cpp/numeric/countl_one
int std::countr_zero(x); // 从最低位(“右”)起连续为 0 的位的数量#include <bit>】https://en.cppreference.com/w/cpp/numeric/countr_zero
int std::countr_one(x); // 从最低位(“右”)起连续为 1 的位的数量#include <bit>】https://en.cppreference.com/w/cpp/numeric/countr_one

bool std::has_single_bit(x);
【#include <bit>】https://en.cppreference.com/w/cpp/numeric/has_single_bit // 判断x是否为二的整数次幂
y = std::bit_ceil(x);
【#include <bit>】https://en.cppreference.com/w/cpp/numeric/bit_ceil       // 不小于x的最小的二的整数次幂
y = std::bit_floor(x);
【#include <bit>】https://en.cppreference.com/w/cpp/numeric/bit_floor      // 不大于x的最大的二的整数次幂

y = std::bit_width(x);
【#include <bit>】https://en.cppreference.com/w/cpp/numeric/bit_width      // 计算存储x所需的位数
y = std::byteswap(x);
【#include <bit>】https://en.cppreference.com/w/cpp/numeric/byteswap       // 翻转给定整数值 x 中的字节
y = std::rotl(x,3); // 左循环移位3位#include <bit>】https://en.cppreference.com/w/cpp/numeric/rotl           // 将 x 左旋 s 位 (循环移位)
y = std::rotr(x,3); // 右循环移位3位#include <bit>】https://en.cppreference.com/w/cpp/numeric/rotr           // 将 x 右旋 s 位 (循环移位)

end.友情链接如有疑问可留言沟通交流end. 友情链接:^{如有疑问可留言沟通交流}

  1. C++常用算术及标准库容器算法(Standard Template Library Containers, STLC)
  2. C++代码片段std::string 字符串分割
  3. C++数据类型及标准库容器(Standard Template Library Containers, STL)
  4. ...

代码调试不易,转载请标明出处!
如果感觉本文对您有帮助,请留下您的赞,您的支持是我坚持写作分享的最大动力,谢谢!

References
0.Standard C++
1.cppreference.com
2.apiref.com/cpp-zh
3.cplusplus.com
4.C++ 标准库参考 | Microsoft Learn
5.C++ 教程 | 菜鸟教程
6.C++ 二进制、字符串、十六进制、十进制
7.C++中substr()函数用法
可以肯定的是学海无涯,这篇文章也会随着对 C++ 的深入学习而持续更新,
欢迎各位在评论区留言进行探讨交流。