目录
1.输出(头文件讲解)
2.格式控制
常用的I/O流控制符
4.各种进制之间的转换(进制大乱斗)
4.1.写在前面
4.2整体框架搭建
4.3菜单函数
4.4用户输入选择(main函数体中)
4.5十进制转N进制函数功能实现
4.6N进制转十进制
4.7M进制转N进制
4.8完整代码
1.输出(头文件讲解)
提到输出,不得不将一下C++的I/O流,也就是我们常用的那个头文件
#include<iostream>
- 在C++中,将数据从一个对象到另一个对象的流动抽象为“流”
- 流在使用前要被建立,使用后要被删除
- 数据的输入与输出是通过I/O流来实现的,cin和cout是预定义的流类对象
- cin用来处理标准输入,即键盘输入
- cout用来处理标准输出,即屏幕输出
- 从流中获取数据的操作称为提取操作,向流中添加数据的操作称为插入操作
2.格式控制
#include<iomanip>
用控制符(manipulators)可以对I/O流的格式进行控制
C++在头文件iomanip定义了控制符对象,可以直接将这些控制符嵌入到I/O语句中进行格式控制
在使用这些控制符时,要在程序的开头包含头文件iomanip。
下表3-2列出了常用的I/O流控制符:
常用的I/O流控制符
控制符 | 描述 | 备注 |
dec hex oct bin | 按10进制输出 按16进制输出 按8进制输出 按2进制输出 | 常量控制符 在iostream中 |
setfill(c) setprecision(n) setw(n) setiosflags(ios::fixed) setiosflags(ios::scientific) setiosflags(ios::left) setiosflags(ios::right) setiosflags(ios::skipws) setiosflags(ios::uppercase) setiosflags(ios::lowercase) setiosflags(ios::showpos) | 设填充字符为c 设置显示小数精度为n位 设域宽为n个字符 小数方式表示 指数表示 左对齐 右对齐 忽略前导空白(用于输入) 16进制数大写输出 16进制数小写输出 输出正数时给出“+”号 | 函数控制符 在iomanip中 |
endl ends | 插入换行符,并刷新流 插入空字符 |
这篇文章的主题是iostream头文件中的四个常用的常量控制符
dec(十进制) hex(十六进制) oct(八进制) bin(二进制)->bintset<自定义的二进制位数>(变量)
3.案例讲解
我们平常敲的int类型的变量初始化值是什么类型的?
比如我们输入一个四位数字1314
#include<iostream>
using namespace std;int main()
{int num = 1314;cout << "默认:" << num << endl;system("pause");return 0;
}
输出结果也是1314,那么这个默认输出的1314是几进制呢?
按照从小到大的顺序
- 从二进制开始尝试(明眼人一看就知道不是二进制,二进制只有洞幺01)
- 而后是八进制(采用0,1,2,3,4,5,6,7八个数字,逢八进1)
- 其次是十进制(满十进一,虽然确定但还是要小心求证)
- 最后是十六进制:
-
英文字母A,B,C,D,E,F分别表示数字10~15
-
计数到F后,再增加1个,就进位
#include<bitset>//使用二进制必须要用到的头文件
#include<iostream>
using namespace std;int main()
{int num = 1314;cout << "默认:" << nuum << endl;cout << "二进制:" << bitset<10>(num) << endl;cout << "八进制:" << oct << num << endl;cout << "十进制" << dec << num << endl;cout << "十六进制:" << hex << num << endl;system("pause");return 0;
}
见证奇迹的时刻到了(其实一点儿也不惊喜__^^__)
值得提一下的是:
- VS的C++版本要借助<bitset>库(头文件),调用其中的方式bitset<len>(num),其中 len是二进- 制输出的位数,提前自定义; num:要转成二进制的数
- C++ 版本 -> cout <<"二进制:"<<bitset<10>(num) <<endl;
- 10是二进制位数,自定义为多少输出就是多少位,高位补0
- 下图的输出例子就补了一个0在最左边
- 以及输出几进制的格式是 cout<<"*进制:"<<进制关键字<<变量<<endl;//可以不换行,换成“ ”也行
得出一个结论,我们平常敲的数据都默认是十进制,而且还有一个没有明说的是,上面这个案例,十进制以外的(二,八,十六)准确来说,应该是:
十进制转二进制 十进制转八进制 十进制转十六进制
那么,怎么反过来转呢?
先看二进制怎么转回十进制
除以2取余的方法:
#include<iostream>
#include<math.h>//pow函数要用到的头文件
using namespace std;
int main()
{unsigned long select, num = 0, d;//定义无符号长整型变量cout << "请输入需要转换的二进制数字:";cin >> select;//录入用户输入的数据for (unsigned long i = 0;select!=0;++i)//因为二进制数字可能是一长串,所以就不能用普通的一般的int来对付{d = select % 10; //用户输入取余于10num = (d)*pow(2, i) + num;select = select / 10;//用户输入整除于10}cout << num << endl;//输出转换成功的十进制数字并刷新流换行system("pause");return 0;
}
输入一个算过的例子验证一下代码是否正确
就截图的那个推算吧 100101110
(还好结果是302 不然差点就打脸了)
再来看个八进制和十六进制之间的互相转换
八进制化为十六进制:
先将八进制化为二进制,再将二进制化为十六进制
例:(712)8 = (1110 0101 0)2 = (1CA)16
十六进制化为八进制:
先用1化4方法,将十六进制化为二进制;再用3并1方法,将二进制化为8制
例: (1CA)16 = (111001010)2 = (712)8
说明:小数点前的高位零和小数点后的低位零可以去除
(中间人还得是二进制)
c++中可以利用
cin>>hex>>a输入十六进制
cin>>oct>>a输入八进制
--------------------------------
利用
cout<<hex<<a输出16进制
cout<<oct<<a输出八进制
cout<<dec<<a输出十进制
4.各种进制之间的转换(进制大乱斗)
4.1.写在前面
学会了之前的十进制转二进制或者二进制转十进制,这个程序就不难实现了
N,M进制是指除了十进制以外的进制
十进制->N进制,N进制->十进制,M进制->N进制(比如八进制转不是十进制的16进制等)
4.2整体框架搭建
头文件,各个头文件用法目的都有注释
命名空间
main函数框架
system("pause");%按任意键继续,提高程序的可读性便于提示用户
return 0;先给程序一个正常退出值,以免后面漏掉了
//进制转换器
#include<iostream>//输入输出要用到的头文件
#include<cstring>//string 字符串要用到的头文件
#include<cmath>//一些数学运算函数,比如pow()
#include <cstdio>//通过使用C标准输入和输出库(cstdio,在C语言中称为stdio.h)
#include <stack>//栈的头文件,栈是基本的数据结构之一,特点是先进后出,就如开进死胡同的车队,先进去的只能最后出来
using namespace std;
int main()
{system("pause");%按任意键继续return 0;%返回正常退出值
}
4.3菜单函数
我们的目的是实现
十进制->N进制,N->十,M->N
所以我们的菜单showMenu要在屏幕上输出以下内容来提示用户本程序的功能有哪些,并且在函数中提示用户输入选项前的数字编号
void showMenu()//展示选项菜单的函数
{cout << "********************进制转换器********************" << endl;cout << "请输入选项前的数字编号,比如1,2,3执行相应功能哦" << endl;cout << "1.十进制转N进制选项" << endl;cout << "2.N进制转十进制选项" << endl;cout << "3.M进制转N进制选项 " << endl;cout << "********************----------********************" << endl;
}
在主程序中调用showMenu
showMenu();//无参无返函数直接用
4.4用户输入选择(main函数体中)
录入用户输入的选项,我们可以选择if(slect==1),else if(slect==2)........
也可以用switch(select) case(1),case(2),case(3),defaut语句
此处我们选择switch case语句
首先定义一个可供用户输入的变量来存储,就叫select吧,并且初始化为0
int select = 0;
我们后续肯定要执行的不只是一次性的程序,而是反复出现的,所以,我们可以把switch,case写进一个死循环中,while(truue),只要是正数就符合此循环,会一直执行
int main()
{int select = 0;while (true){showMenu();//显示菜单cin >> select;//用户输入的数据,菜单选项1或者2switch (select){case 1:cout << "录入选项正确,继续执行操作" << endl;break;case 2:cout << "录入选项正确,继续执行操作" << endl;break;case 3:cout << "录入选项正确,继续执行操作" << endl;defaut:cout << "录入选项错误,请重新输入选项1或2,3" << endl;}}system("pause");return 0;
}
此处会一直出现菜单,影响观感,所以后面我们会在每个case调用的函数执行完毕后执行清屏,就只有一个菜单啦
之所以会在每个case后面输出一行提示符,是为了测试此代码,后续可删掉
PS:先showMenu再cin>>select,否则会出现如下截图,毫无防备和提示
4.5十进制转N进制函数功能实现
我们最常见的进制转换就是十进制转换为二进制了,就是不停的作除法,取余数。
例如:十进制的10转换为二进制
10÷2=5···0
5÷2=2···1
2÷2=1···0
1÷2=0···1
直到商为0,然后把余数倒着写,所以10的二进制表示为1010。
会了十进制转换为二进制,那么十进制转换为任意进制也就迎刃而解了,只要不停的除法和取余就好了。
代码有注释,凑合着看吧,敲了一天键盘,容我偷个懒(--^^--)
char int2char(int target)//把整数转换成对应进制的字符,比如10的16进制表示为A
{if (target < 10){return target + '0';}else{return target - 10 + 'A';}
}
//现在可以真正实现任意进制了
void Ten2N(int num, int n)//此代码本身只能转换10以内的进制,比如16进制就不能转换了,所以在调用前,应加上一段改进代码
{stack<char>s;//创建栈char类型变量s,方便后续调用栈头文件中的函数,用.点访问//stack<int>s; 就是int 类型的变量if (num == 0)//入栈{s.push(0);//如果用户输入的数字是0,stack::push();//在栈顶增加元素cout << "输入有误,请重新输入!" << endl;}else if (num < 0)//入栈{s.push(0);//如果用户输入的是负数,stack::push();//在栈顶增加元素}else//用户输入的是正数,执行以下代码{while (num){s.push(int2char(num%n));//在余数入栈的时候加工一下,把int转换为charnum = num / n;//num /=n}//把栈中的余数输出,栈未满,输出while (!s.empty())//栈未满{printf("%d", s.top());//提取栈顶元素,top(),返回栈顶的引用s.pop();//pop(), 返回void,出栈,输出}}printf("\n");//打印system("pause");//要写在cls清屏前面,否则,清完屏之后就只有按任意键继续了system("cls");
}
声明,如果没有int2char函数,则是Ten2N函数就只能转换10进制以内的,比如16进制就不能转换了
主函数中的调用
case 1:{int num = 0;//十进制原始数据int n = 0;//进制代码cout << "请输入您要转换的十进制数字:" << endl;cin >> num;cout << "请输入您要转换的进制,只需输入相应数字,比如十六进制输入16,八进制输入8:" << endl;cin >> n;Ten2N(num, n);break;}
4.6N进制转十进制
会了十进制转换为N进制,那么把N进制转换为十进制倒着来就好了,不停的乘N,加上余数。
例如:二进制的1010转换为十进制
0*2+1=1
1*2+0=2
2*2+1=5
5*2+0=10
函数部分,需要先把用户输入的字符串转换成可运算的数字(因为转换结果是十进制,纯阿拉伯数字,而输入的可能是多个字符的十六进制F带啥的)
int char2int(char target)
{if (target >= '0'&&target <= '9'){return target - '0';}else{return target - 'A' + 10;//和int2char刚好反过来}
}//至于为什么是string类型,比如十六进制0x10,就是十进制的0
void M2T(string str, int m)//次函数寓意为把N进制的数字M转换为十进制T,Ten
{int num = 0;//该数字在十进制下的表示,待会儿要输出的转换结果for (int i = 0; i < str.size(); ++i)//众所周知进制转换公式= for(int i = 1; i <= 数字.size(); ++i){第i位数*维权^进制{num *= m;//num=num*mnum += char2int(str[i]);//把相应源数据转换成int类型数字,再让其i自增一,最后赋值给要输出的十进制数字num}printf("%d\n", num);//输出十进制有符号整数 ,换行,填入的数据是numsystem("pause");system("cls");
}
主函数体内的调用
case 2:{string str;int m = 0;cout << "输入原始数据" << endl;cin >> str;//如果 显示不能输入string字符串类型,则加一个头文件#include<string>cout << "输入原始数据的进制数,比如二进制输入2" << endl;cin >> m;M2T(str, m);break;}
对照下面这个表 来输出,验证代码是否正确
比如,输入A,16进制,输出的10进制应该是10
输出正确,也可以多拿几个验证
4.7M进制转N进制
实现把M进制转换成N进制了,思路是先把M进制转换成十进制,然后再把十进制的数转换成N进制
C++警告
warning C4018: “<”: 有符号/无符号不匹配
警告代码
for (int i = 0; i < str.size(); ++i)//众所周知进制转换公式= for(int i = 1; i <= 数字.size(); ++i){第i位数*维权^进制{num *= m;//num=num*mnum += char2int(str[i]);//把相应源数据转换成int类型数字,再让其i自增一,最后赋值给要输出的十进制数字num}
警告原因:
matchPoint 是一个Vector容器,matchPoint .size() 在容器说明中 被定义为: unsigned int 类型, 而i是int 类型,所以会出现: 有符号/无符号不匹配警告
修改方法:
将i改为unsigned int 类型即可
for (unsigned int i = 0; i < str.size(); ++i)//众所周知进制转换公式= for(int i = 1; i <= 数字.size(); ++i){第i位数*维权^进制{num *= m;//num=num*mnum += char2int(str[i]);//把相应源数据转换成int类型数字,再让其i自增一,最后赋值给要输出的十进制数字num}
函数完整代码如下,inr2char和char2int函数再前面已经写好了,直接调用就行,其实就是综合了前两个进制转化,以十进制作为媒介而已
//N进制转十进制
int covM2T(string str,int m)
{int num = 0;//原始数据在10进制下的表示for (unsigned int i = 0; i < str.size(); ++i){num *= m;//mum=mun*mnum += char2int(str[i]);}return num;//此处的返回值便于将M2T的结果移交给T2N
}
//十进制转N进制
void covT2N(int num, int n)
{stack<char>s;//栈char类型变量swhile (num){s.push(int2char(num%n));//入栈num /= n;}if (s.empty())//栈空{printf("0");}while (!s.empty())//栈非空{printf("%c", s.top());s.pop();//栈输出,默认结果}printf("\n");//打印结果system("pause");system("cls");
}
主函数中的调用
case 3:{int m = 0, n = 0;string str;cout << "请输入要转换的原始数据:" << endl;cin >> str;cout << "请输入原始数据的进制:" << endl;cin >> m;int num = covM2T(str, m);cout << "请输入要转换的进制:" << endl;cin >> n;covT2N(num, n);break;}
结果验证(二进制1000,转16进制,中间数十进制的1000是8,16进制是8)
结果正确
OVER!
4.8完整代码
//进制转换器
#include<iostream>//输入输出要用到的头文件
#include<string>//string字符串用到
#include<cstring>//string 字符串要用到的头文件
#include<cmath>//一些数学运算函数,比如pow()
#include <cstdio>//通过使用C标准输入和输出库(cstdio,在C语言中称为stdio.h)
#include <stack>//栈的头文件,栈是基本的数据结构之一,特点是先进后出,就如开进死胡同的车队,先进去的只能最后出来
using namespace std;void showMenu()//展示选项菜单的函数
{cout << "********************进制转换器********************" << endl;cout << "请输入选项前的数字编号,比如1,2,3执行相应功能哦" << endl;cout << "1.十进制转N进制选项" << endl;cout << "2.N进制转十进制选项" << endl;cout << "3.M进制转N进制选项 " << endl;cout << "********************----------********************" << endl;
}char int2char(int target)//把整数转换成对应进制的字符,比如10的16进制表示为A
{if (target < 10){return target + '0';}else{return target - 10 + 'A';}
}
//现在可以真正实现任意进制了
void Ten2N(int num, int n)//此代码本身只能转换10以内的进制,比如16进制就不能转换了,所以在调用前,应加上一段改进代码
{stack<char>s;//创建栈char类型变量s,方便后续调用栈头文件中的函数,用.点访问//stack<int>s; 就是int 类型的变量if (num == 0)//入栈{s.push(0);//如果用户输入的数字是0,stack::push();//在栈顶增加元素cout << "输入有误,请重新输入!" << endl;}else if (num < 0)//入栈{s.push(0);//如果用户输入的是负数,stack::push();//在栈顶增加元素}else//用户输入的是正数,执行以下代码{while (num){s.push(int2char(num%n));//在余数入栈的时候加工一下,把int转换为charnum = num / n;//num /=n}//把栈中的余数输出,栈未满,输出while (!s.empty())//栈未满{printf("%d", s.top());//提取栈顶元素,top(),返回栈顶的引用s.pop();//pop(), 返回void,出栈,输出}}printf("\n");//打印system("pause");//要写在cls清屏前面,否则,清完屏之后就只有按任意键继续了system("cls");
}int char2int(char target)
{if (target >= '0'&&target <= '9'){return target - '0';}else{return target - 'A' + 10;//和int2char刚好反过来}
}//至于为什么是string类型,比如十六进制0x10,就是十进制的0
void M2T(string str, int m)//次函数寓意为把N进制的数字M转换为十进制T,Ten
{int num = 0;//该数字在十进制下的表示,待会儿要输出的转换结果for (unsigned int i = 0; i < str.size(); ++i)//众所周知进制转换公式= for(int i = 1; i <= 数字.size(); ++i){第i位数*维权^进制{num *= m;//num=num*mnum += char2int(str[i]);//把相应源数据转换成int类型数字,再让其i自增一,最后赋值给要输出的十进制数字num}printf("%d\n", num);//输出十进制有符号整数 ,换行,填入的数据是numsystem("pause");system("cls");
}
//N进制转十进制
int covM2T(string str,int m)
{int num = 0;//原始数据在10进制下的表示for (unsigned int i = 0; i < str.size(); ++i){num *= m;//mum=mun*mnum += char2int(str[i]);}return num;//此处的返回值便于将M2T的结果移交给T2N
}
//十进制转N进制
void covT2N(int num, int n)
{stack<char>s;//栈char类型变量swhile (num){s.push(int2char(num%n));//入栈num /= n;}if (s.empty())//栈空{printf("0");}while (!s.empty())//栈非空{printf("%c", s.top());s.pop();//栈输出,默认结果}printf("\n");//打印结果system("pause");system("cls");
}int main()
{int select = 0;//用户输入的选项while (true){showMenu();//显示菜单cin >> select;//用户输入的数据,菜单选项1或者2switch (select){case 1:{int num = 0;//十进制原始数据int n = 0;//进制代码cout << "请输入您要转换的十进制数字:" << endl;cin >> num;cout << "请输入您要转换的进制,只需输入相应数字,比如十六进制输入16,八进制输入8:" << endl;cin >> n;Ten2N(num, n);break;}case 2:{string str;int m = 0;cout << "输入原始数据" << endl;cin >> str;//如果 显示不能输入string字符串类型,则加一个头文件#include<string>cout << "输入原始数据的进制数,比如二进制输入2" << endl;cin >> m;M2T(str, m);break;}case 3:{int m = 0, n = 0;string str;cout << "请输入要转换的原始数据:" << endl;cin >> str;cout << "请输入原始数据的进制:" << endl;cin >> m;int num = covM2T(str, m);cout << "请输入要转换的进制:" << endl;cin >> n;covT2N(num, n);break;}default:cout << "输入选项代码有误" << endl;}}system("pause");return 0;
}
PS:while(!s.empty)是栈非空不是栈满这里到后面才发现,就没改了,细心的小朋友肯定早就发现了
看都看完了,点个赞再走呗