目录
原文章:
此文章为作者本人搬运至该网站。
说在前头:
既然是转到c++,那就要遵循c++语言的基本格式以及写法。
一、外部格式:
1.首先,我们先从熟悉的部分开始,一个最最基础的c语言代码显然包含以下格式:
#include<stdio.h>
int main() {
//代码内容
return 0;
}
包含include头文件、main函数以及里面的return,
但是到了c++,include里面的就要换成
#include<iostream>
using namespace std;
int main() {
//代码内容
return 0;
}
其中#include<iostream>包含了标准输入/输出流的内容,也就和stdio.h内容差不多。
(可能会有些小伙伴好奇,为什么stdio.h后面带了个.h,iostream没有,我查到的就是,其实也是有iostream.h的,不过c++已经不再支持后缀为.h的头文件了,所以就不用了)
2.下面这个usingnamespace std;,也是必备内容,其实我们记住就好,如果非要探究其原理的话,可以去看一下这个文章:
C++ using namespace std 详解-CSDN博客
【C++】C++中“std::“是什么意思?起什么作用?-CSDN博客
反正我了解到的就是,如果你不写这句话,那么后面的输入输出语句就都需要加上个 std:: 的前缀。所以最好还是加上。
3.另外main函数以及return还是保持不变的。
二、输入输出语句:
c语言的最基本的输入输出语句:
#include<stdio.h>
int main() {
int a;
scanf("%d", &a);
printf("%d", a);
return 0;
}
而到了c++中,是这样的:
#include<iostream>
using namespace std;
int main() {
int a;
cin >> a;
cout << a;
return 0;
}
其中scanf和printf分别换成了 cin >> 和 cout <<,
并且经过我自身两个软件的测试,在只有#include<iostream>的情况下,也是可以用scanf和printf的。
C算法:C++中cin和scanf的区别(总结)!!!-CSDN博客
(ps:上面这个链接中所写的第一个区别,我经过测试并没有实现)
对我来说,cin和cout的一大优势就是方便,不用像scanf和printf一样对不同的数据类型还要写%d,%f什么的。
1. cin>>与cout<< の简单介绍:
这里是省流版:
(1). cin对于每个数据的输出,都要在其左边加上个>>,而cin和scanf对于空格和tab或换行时,都是自动忽略
#include <iostream>
using namespace std;
int main() {
int a;
int b;
char c;
cin>>a>>b>>c;
return 0;
}
而这样的话,那么就和scanf对于缓冲区这一部分有所不同,具体可以看这个文章:
scanf的缓冲区问题_什么时候会出现scanf的缓冲问题-CSDN博客
(在这里顺便回顾一下scanf的缓冲区的问题,更便于讲解cin的用法)
int a;
int b;
char op;
printf("输入两个数:");
scanf("%d%d", &a,&b);
printf("输入操作方法:");
scanf("%c", &op);
printf(" %d %c %d = ", a, op, b);
文中在实现这个代码时候,会出现:
刚输入完1,空格,2按下回车后,下面那个char类型的op还没来得及输入就结束程序了。
这里的原因其实是这个op数据元素是char类型的,且没有fflush清除缓存,就会有由于第一个scanf之后的回车没有读取(按照 1+空格+2+回车 的格式输入),那么在下一个scanf的时候,由于op是char,那么会把op赋予为回车,这个scanf直接结束。
但是如果不是char类型,而是int类型,或者有fflush清除缓存,那么就不会出现这个情况。
这一点还是挺麻烦的,我原本以为只会在getchar里面出现。
不过cin就不一样了!
#include <iostream>
using namespace std;
int main() {
int a;
int b;
char op;
cin>>a>>b;
cin>>op;
cout <<a<<b<<endl<<op<<endl;
return 0;
}
这里经过本人测试,无论是char类型还是int类型都不会出现上述问题。
应该是因为当 cin>> 从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>> 会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。
但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>> 不做处理。
(2). cout也挺简单的,
不过首先要先分清,cin右边的符号是 >> 两个大于号,而cout则是 << 两个小于号,这一点要看清!
另外就是上面会有个endl,这个其实就是换行符,和printf中的'\n'一个东西,当然你也可以写:
cout << a << "\nhello\n" << b << '\n' << op <<endl;
左边这个双引号里面的就是输出文本,以及\n这样的特殊负号,中间这个'\n'则是用符号输出,最右边那个endl不多阐述,
就我的经历来看,还是写endl的人比较多。
那么cin和cout基本上就是这样,挺简单的。
2.cin.get() の介绍:
cin.get()为cin的另一版,大致类似于getchar()与gets()的融合,但是也有自己的特异点:
(1).输入一个字符:
这种就类似于getchar(),无论你输入多少个字符,其只接收第一个输入的字符。
需要注意的是,cin.get() 只用于char类型的数据,输入的1也是char类型而不是int类型。
用法:ch = cin.get(); //ch为char类型的数据
或者:cin.get(ch);
#include <iostream>
using namespace std;
int main() {
char ch;
ch = cin.get();
//或cin.get(ch);
cout << ch;
//输入:abc,输出:a
return 0;
}
(*)不过这里有一点需要注意的是,那就是cin.get()和getchar()一样,不会跳过最后的输入完成后的回车键,也就是说,如果你在上面的ch = cin.get();后面又加上了个一样的ch = cin.get();,并且只输入一个字符后回车,就会出现如下场景:
最后cout输出的是回车而不是a。这个情况大家应该已经很熟悉了。
(2).输入字符串数组:
这种类似于gets(),不过与其不同的是,cin.get()输入的是特定长度的字符串数组。
用法:cin.get(arr, 5);
在这里arr为数组名,5为所接收的字符数,不过还要减去1个。也就是说,实际接收的字符有4个,最后一个字符为自动补上的'\0'终止符(其ASCII码值为0,如果这一点不清楚的话可以查一下
深入理解c语言——‘\0’ ,‘0’, “0” ,0之间的区别-CSDN博客
这个)
#include <iostream>
using namespace std;
int main() {
char arr[10];
cin.get(arr,5);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
cout << arr[3] << endl << "-------";
cout << arr[4] << "test" << endl;
printf("第五个输入字符的ASCII值为:%d", arr[4]);
return 0;
}
以上代码测试结果如下:
通过cin.get(arr,5)输入abcdef,最终从arr[0]到arr[3]这4个数组元素分别被赋值为abcd,但是a[4]并没有赋上值(------和test之间没有任何东西,连空格也没有),这个就是cin.get(arr,5)的作用。
通过后面的printf可以得出a[4]的元素的ASCII值为0,就是'\0'终止符。
而因为cin.get函数里面的数字写的是5,那么即使这个原数组开辟的空间数大于5且输入的字符也大于了5个,也只有前4个元素被成功赋值,后面都只是'\0'。
另外,cin.get(arr,5)和 ch = cin.get() 对于换行符都是一样的不丢弃法则,比如:
#include <iostream>
using namespace std;
int main() {
char a[10];
char b[10];
cin.get(a,5);
cin.get(b,5);
cout << a << "-------" << b;
return 0;
}
这里只输入了一次的123456789,但是最后a和b的数组都有赋值。
如果想要两次分别输入a和b的话,那么就需要在两个cin中间插入个getchar(),或者cin.get()来吞掉回车(换行符)。
3.cin.getline() の介绍:
cin.getline()和cin.get(arr,5)一样是用来接收字符串数组的,不过前者相较于后者有两个不同的地方:
(1). cin.getline()可以接收带空格的字符串(经测试,Tab键也是可以的),比如:
#include <iostream>
using namespace std;
int main () {
char arr[10];
cin.getline(arr, 5);
cout << arr[0] << "---" <<endl;
cout << arr[1] << "---" <<endl;
cout << arr[2] << "---" <<endl;
cout << arr[3] << "---" <<endl;
cout << arr[4] << "---" <<endl;
return 0;
}
在这里每个数字之间都有空格作间隔,最后的输出结果如图,1和2后面的空格都被赋值给arr[1]和arr[3],而最后一个arr[4]也是和cin.get一样,不存入,是'\0'。
如果按tab键的话就是这样
(2). 其实cin.getline()函数的完整形式有三个参数:
cin.getline(字符数组名, 字符个数, 结束标志);
前两个很明显就是刚才讲到的,但是这最后一个结束标志是什么呢?
结束标志也是个字符,也就是让这个函数在遇到与这个结束标志的字符相同的字符时,就停止输入。
如果其还未达到输入的个数上限的话(比如允许输入8个字符,但是在第3个字符处就遇到了与结束标志相同的字符),那么其也不会因为未达到上限而继续读取,而是会立即停下。
例如:
#include <iostream>
using namespace std;
int main() {
char arr[10];
cin.getline(arr, 8, 'z');
cout << arr << endl;
return 0;
}
这个代码中的 cin.getline(arr,8,'z'); 就是对arr读取7个字符(还知道为什么是7个吗?第8个的位置要是'\0'呀!),然后在此期间,对每一个读取的字符进行判断,判断其是否为字符z,如果不是,则继续读取下一个字符,如果是的话,那么就不读取这个字符,并结束读取。
在这里我在4个a后面输入了个z,结果程序只读取并赋值了前4个a,遇到z也不赋值,即使数组开辟了8个空间。
4.getline() の介绍:
C++:cin、cin.getline()、getline()的用法_getline(cin,s)函数用法-CSDN博客
getline()也是输入字符串的函数,同样可以读取空格和tab键,不过需要额外加上一个头文件:
#include <string>
既然说到这个头文件,那么就不得不提到#include <string.h>了,
它们两个都是头文件,但是并不相同!
C++中#include<string>与#include<string.h>的区别_#include <string>-CSDN博客
编程小白C语言#include「string.h」常用总结_include<string.h>的作用-CSDN博客
简单来说,string.h可以使用strlen()求字符串数组的长度,strcmp()比较两个字符串数组是否一样、strcpy()字符串数组复制、strcat()字符串数组连接等操作,也是我们初学c语言时候就会了解到的头文件。
而string则定义了一个新的数据类型——字符串:
C++中的String的常用函数用法总结_string函数-CSDN博客
使用string头文件后,我们就可以通过 string str; 这样的方式,像 int a; 一样直接定义数据元素,字符串就不需要再用数组的方式定义了。
#include<iostream>
#include<string>
using namespace std;
int main () {
string str;
getline(cin, str);
cout << str << endl;
return 0;
}
这里比较简单我就不展示运行结果了。
而需要注意的是,这个getline是不受回车影响的,也就是两个getline可以直接并排放:
#include<iostream>
#include<string>
using namespace std;
int main () {
string str, str2;
getline(cin, str);
getline(cin, str2);
cout << str << endl;
cout << str2 << endl;
return 0;
}
运行结果
另外就是<string>也有很多自带的关于字符串的函数,基本上在这里都有写到:
C++中的String的常用函数用法总结_string函数-CSDN博客
不过到后面真正学到STL的时候应该还会用上,就之后再说吧。
5.一个注意点:
之前刚说过cin会跳过回车,现在getline()又出了个幺蛾子。。。
如下:
#include<iostream>
#include<string>
using namespace std;
int main () {
string str;
int a;
cin >> a;
getline(cin, str);
cout << a << endl;
cout << str << endl;
return 0;
}
当我们输入1赋值给a之后,在后面的getline()里面就会把回车键赋值给str字符串,从而str输出的也是回车。
也就是很常见的回车问题。
cin和>>遇到回车时的处理_cin>>m>>n;-CSDN博客
对于此,我看了这篇文章,大致意思就是:
cincin不丢会弃回车符,但是 >> 会跳过回车符。所以cin>>出现的时候,其会直接跳过之前遗留的回车符。但是getline()并不会。
所以我们还需要在getline()和cin中间加上个cin.get()或者getchar(),
当然如果觉得比较麻烦的话,也可以在真正写代码的时候自行测试一下,就记住了~~