(一)读取各种形式的数据
一、C语言读取各种形式的数据
主要通过scanf()、getchar()、 gets()三个函数来实现:
(1) scanf: int scanf(格式化字符串,指针....); 返回顺利读到自己的值的变量数
注意点1:由于第二个参数后面开始就是指针了,所以读取字符串不用取地址符
注意点2:double类型用%lf ,float用%f,不可混淆否则值会错的。
注意点3:scanf会将tab space enter三个值认为一个值就是分隔符,代码:
float q,m;
scanf("%f %f",&q,&m);
printf("%f%f",q,m);
控制台:
3 3
3.0000003.000000
注意点4:scanf读取字符串时,需要关注实际读取的字符串长度
char a[10]; //最多读9个字节
scanf("%7s",a); //限定读7个
printf(a);
控制台:
12345678 //输入8个数字
1234567 //输出7个数字
注意点5:scanf读取过程中会略去分隔符,但是最后一个enter会被保留下来在缓冲区中。我们可以利用getchar()来证明这一点
(2) getchar()函数,函数原型:int getchar(void)
getchar()函数可以在用户输入回车后从缓冲区当中取出一个字符,返回该字符的ASCII码(0-127)。当读取到EOF时,会返回--1,windows下我们可以通过ctrl+z实现输入EOF,(EOF在不同shell是不同的,可能是-1)为了验证scanf的注意点4,我们有这样的代码:
int a,b;
scanf("%d %d",&a,&b); //输入33_33
putchar(getchar());
printf("%s","sb");
输出:
33 33
sb
可见33 33与sb之间多了一个\n,这个\n正是scanf剩下的。
(3) gets函数 我们在读取含有空格键的字符串的时候,scanf就很不合适了,为此我们有了gets函数:
char a[20]={0};
scanf("%s",a); //输入 hello world
gets(a);
printf("%s\n",a);
putchar(getchar()); //被要求再次输入 我们输入8
输出界面:
hello world //本行是输入行
_world88 // 88也是我们的输入 scanf拿走了hello 留下_world 被gets全部读走 这里就可以打印出来了
8 //getchar()只读了一个字节 这里并没有打印回车,回车是我自己打的,可见gets函数读走内容时,删掉了缓冲区里的回车键
我们可以看见,此处putchar(getchar())并没有换行,而是要求我们输入,可见gets函数不像scanf那样会留下尾巴,一口气全打包带走了,清空了缓冲区。
二、C++读取各种形式的数据
主要是三个函数cin,cin.get(),cin.getline()函数。
(1) cin
单独的cin和scanf的功能是类似的,如下两行代码:
short a = 0;
cin >> a; //输入656563 我故意让656563大于short的最大值32767 发现输出报错为0了,这个逻辑是对
cout <<hex << a; //iomainp是需要的
//putchar(getchar());
if (getchar() == '\n') {
cout << "is space!";
cout << endl;
}
cout << "sb" << endl;
控制台界面:
0is space! //可以看到cin与scanf一样留下了一个回车键,被我读取到了
sb //这个换行sb是我endl一下产生的,原先的回车已经被getchar掉了。
但是scanf在同样的代码下表现就不一样了,scanf在读取时是忽略内存大小的,我们看:
short b = 0;
scanf("%hd",&b); //short decimal 所以这是hd 输入656563
printf("%x", b);
if (getchar() == '\n') {
printf( "is space!");
printf("\n");
}
printf("%s","sb");
控制台界面:
4b3is space! //656563的实际转16进制是a04b3 可见scanf对于溢出有些问题
sb
(2) cin.get()函数:
这个与C语言当中的getchar()是一模一样的,就是读一个字符,语法是:char b=cin.get();或者cin.get(b);但拓展了新用法可以接收字符串,语法是 cin.get(字符数组,长度),参数中长度比实际读取长度大1,\n会留在缓冲区当中。
代码:
char a[20]; //该值不可以比读入的位数小,否则会崩溃
cin.get(a, 15); //即使输入的内容若太短,会提前截止,结尾的\n也不会进入字符串
cout << a;
控制台界面:
0123456789 0123456789 0123456789
0123456789 0123请按任意键继续. . . //读取15-1=14个字符,最后一个以‘\0’填充
(3) cin.getline()函数
用于读取一个字符串,与cin.get()函数不同,这个函数在读取结束后会删除缓冲区当中的\n,特色是限长度
代码,与C语言的gets函数是一致的:
char a[20];
cin.getline(a, 5); //输入12345
cout << a;
if (cin.get() == '\n') {
cout << "stupid" << endl;
} //若使用get函数会只出现一个 stupid而不是两个或更多
if (cin.get() == '\n') {
cout << "stupid" << endl; //用getline则一个stupid都没有
}
控制台界面:
12345 //输入的值
1234请按任意键继续. . . //实际读取了4个字符,自己增加一个‘\0’
(4)getline函数:特色是限字符
#include<string>//getline包含在string头文件里
#include<iostream>
using namespace std;
int main()
{
string str;
getline(cin, str, '#');
char c = getchar();
cout << str << ' ' << c << endl;
return 0;
}
控制台:
88888#77
88888 7 //分隔符被抛弃掉了
配合cstdio中与C语言相同的gets函数,分别的特色是:
1.gets(字符串变量) 单个参数,啥都不限,很容易溢出
2.cin.getline(char[] s,unsigned int num) 两个参数,一个字符串,一个长度,限长度
3.getline(inputstream input,string s,char c) 三个参数,一个输入流,一个string对象,一个字符,限字符,需要<string>
三、Java读取各种形式的数据
Java的读数据应该是最简单的了,基本的形式是:
Scanner input=new Scanner(System.in); //参数为任一输入流
Input对象具有next,nextLine,nextInt,nextDouble,hasNext,hasNextLine,hasNextInt,hasNextDouble,这配套的四对方法。
next方法:对于输入流当中进行查找,将间隔符之前的内容返回回来成一个字符串,若找不到会发生阻滞等待新的元素,下同。
nextLine方法:对于输入流当中进行查找,将回车符之前的内容返回回来成一个字符串。
nextInt方法:对于输入流当中进行查找,将回车符之前的内容返回回来成整数,会留下后面的回车键。
(二)格式化输出
输出主要的问题集中在:
1.整数格式化输出,细节包括:宽度与填充,左右对齐,正负号,进制,
2.浮点数格式化输出:细节包括精度(小数点后位数),科学计数法输出
3.字符的格式化输出
4.字符串的输出
一、C语言格式化输出:printf函数与sprintf函数 二者需要<stdio.h>头文件,printf的语法为
printf(“格式化字符串”,可变参数列表)
其中格式化字符串包括普通字符和转换字符,C语言的格式化输出时由转换字符决定的。
(1)整数的格式化输出:默认的转换字符是%d
1. 宽度与填充:在d之前加数字即可指定宽度,宽度指的太小是无效的。
int num=100;
printf("%4d",num); //输出 _100 ,_代表空格键,
printf(“%04d”,num); //输出0100,前面加0代表填充
2. 左右对齐:excel经验告诉我们数据都是右对齐的,为了实现左对齐,就要加负号。例如
printf("%-4d",num);//输出100_
3. 正负号:主要是如何输出一个正号
printf("%+4d",num); /*输出+100
*/C语言里转换字符负号左对齐,正号出正号
4. 进制:8进改用o,十六进制改为x或者X
printf("%o",num); //输出144,不可以用大写O的,
printf("%o%%",num);//输出144%,想输出%可以%%
(2)浮点数的格式化输出,默认的转换字符是%f
1. 精度(小数点位数):在f前加小数点即可
double num=100;
printf("%.3f",num); //输出100.000
2. 科学计数法输出(%e和%g)
%e是强制科学计数法:
double num=1234567.3879556913;
printf("%13.5e",num); //输出_1.23457e+006
%g是在指数整数时大于等于6,负数时大于等于5才科学计数:
double num=0.00003;
printf("%g\n",num); //输出3e-005 指数绝对值已经大于4了
printf("%g\n",num*10); //输出0.0003 指数绝对值刚好4不行
(3)字符的格式化输出
1. 借助转换字符%c:
int num1=65;
printf("%c",num1); //输出一个A
2. 借助putchar()函数,函数原型:int putchar(int c),但是c实际上只能是一个字节的char,0-127之间
putchar函数的参数是数字(ASCII码),变量或者字符本身:
char a='A';
putchar(a);
putchar('A');
putchar(65); //输出AAA
(4)字符串的格式化输出:
1. 借助转换字符%s
char q[20]="421023198902345678";
printf("%7.5s",q); //输出__42102 7代表位宽 5代表字符个数
2. 利用sprintf函数:实际上该函数与printf函数的区别在于它并非标准输出,而是将内容送进一个字符串里去了。
语法:int sprintf(char型指针, 格式化字符串,可变参数列表);
//第2个到最后一个参数和printf是一样的,第一个参数是生成的新字符串,返回值int等于新字符串的长度。
我们可以通过这个来做一些字符串拼接的工作:
char p[20]={0};
char q[20]="1234567891067891011";
int qq=sprintf(p,"%-.8s%s",q+6,"you are stupid");
printf("%s %d",p,qq); //输出 78910678you are stupid 22
二、C++语言格式化输出
C++的格式化输出主要是两种情况,一是包含<iomanip>头文件,通过操纵符,进行简单的操作。二是使用cout的成员函数来控制。
(1)整数的格式化输出
1. 宽度与填充
若采用操纵符setw(整数n)与setfill(字符c):
char a[20];
cin.get(a, 5);//输入1234
cin.get(); //发挥getchar功能,去掉上一次get剩下的\n
cout << setfill('q')<<setw(8) << a << endl; //setw()与setfill()操纵符
控制台界面:
1234
qqqq1234 //默认右对齐,用q填满了左边剩下的四位
请按任意键继续. . .
若采用cout的成员函数cout.fill(字符),cout.width(整数)来实现:输入输出相同,源代码是:
char a[20];
cin.get(a, 5);
cin.get();
cout.fill('q');
cout.width(8);
cout << a << endl;
2. 左右对齐
操纵符不能完成左右对齐,此时需要cout的成员函数cout.setf(),setf()函数的参数是格式标志,完成左右对齐的格式标志是ios::left和ios::right(默认右对齐),例如:
char a[20];
cin.get(a, 5); //输入1234
cin.get();
cout.setf(ios::left); //左对齐
cout.fill('q'); //填充为q
cout.width(8); //宽度8,右侧空出4个位置放q
cout << a << endl;
融合二者特点有:
操纵符:setiosflag(格式标志)也是一种操纵符。
3. 正负号:也是只能由cout的成员函数setf()实现,格式表示是ios::showpos
例如:
int num = 0;
cin >> num; //输入55
cout.setf(ios::left); //左对齐
cout.setf(ios::showpos); //show positive 显示正号
cout << num << endl; //输出 +55
4. 进制
操纵符方法:oct,dec,hex:与cout的成员函数setf(),unsetf() :
int num = 0;
int n = 88;
cin >> num;//输入98
cout << hex << num << endl; //输出62,没什么好说的
cout << n<<endl;//此时cout仍然是16进制状态,输出58!
cout.unsetf(ios::hex);//我们先关掉这个十六进制状态,这步不能省略!
cout.setf(ios::oct);//开启8进制的状态
cout << num << endl;//输出142 正确
实际上用成员函数设定输出格式时,即使是以前没有设过格式,这里也需要先cout.unsetf(ios::dec)来取消一遍。不扫干净屋子就不能搬进新家具。
(2)浮点数的格式化输出
1. 精度
系统默认六位小数,精度可以用操纵符setprecision()或者成员函数precision()实现,此处精度和C语言不同,此处的精度是有效数字的位数
double num = 0;
cin >> num;
cout.width(12);
cout.precision(10);
cout << num << endl;
cout <</*setprecision(20)<<*/num<< endl; //放成20位,有效数字会延长
控制台界面:
3.335465132132115
3.335465132//cout.precision(10)拿走了10位有效数字,小数点一位,默认右对齐,左边空一位
3.335465132//系统默认浮点数输出六位有效数字,也是10位precison的设定,可见precision可跨界,而width()不可以,这边并没有出现空位现象
2. 科学计数法:
采用setiosflag(ios::scientific)操纵符或成员函数setf(ios::scientific),这里控制精度也是由cout.precision()函数或者setprecision()操纵符实现的,不过在科学计数法的前提下,精度设置和C语言一致了,就是小数点后的位数.如果不设置,默认也是6位小数的。
double num = 0;
cin >> num;
cout.width(6);
cout.precision(4);
cout.setf(ios::scientific);
cout << num << endl;
控制台界面:
33.515164203205
3.3515e+01 //4位小数
(3)字符的格式化输出
C语言的putchar在C++中仍然使用的,比较C++的cout和putchar,二者直接输出65,cout真的65,putchar是输出A的。
(4)字符串的格式化输出
字符串的拼接是通过插入运算符级联而成。没什么好说的。
三、Java语言格式化输出
完全继承了C语言的输出方式,在System.out.printf中实现。