C++:带类的C
也就是说,C语言中的解决方案放到C++中仍然可以使用
C语言的标准输入输出函数,需要包含头文件
在C++中,只需要包含头文件
,就可以使用C中的输入输出函数
stdin
和stdout
stdin
输入流stdin
输入流,是一个文件描述符(Linux)或者文件句柄(Windows)。其对应着输入区域,通常指键盘设备的输入。在绝大多数时候stdin
可以被直接认为是键盘缓冲区。由于Unix的I/O重定向,可以将文件流重定向到任意文件和设备中,所以这里把stdin
视为一个对应输入的文件。
stdin
是行缓冲I/O。在使用键盘键入字符的时候,键入的字符会被放到键盘自身的缓存中(键盘硬件设备中的一部分)。在遇到换行符后,操作系统才会进行同步,将键盘缓存中的字符读入到stdin
对应的内存中,叫做输入缓存区。所有从stdin
读取数据的函数,都是从电脑内存中的输入缓存区读入数据。
stdout
输出流。对应输出区域,通常指屏幕设备的输出,被认为是屏幕缓冲区。stdout
也是行缓冲I/O。用户打印数据时,数据首先从用户程度到stdout
所对应的输出缓冲区中。而只有缓存遇到了换行符\n
、缓存满了、缓存被刷新了、stdout关闭等情况,数据才会从stdout
输出缓冲区到终端显示
stderr
是标准错误流,是无缓冲的,会立即输出到文件或输出设备上。
scanf()
函数语法:int scanf(const char *format, ...);
EOF
**目的:**从标准输入流stdin
中读取输入,并按照提供的format
来浏览输入
**操作:**打印引号内字符串 ,将格式说明符替换成对应变量
gets()
函数语法:char *gets(char *s);
作用:
从stdin读取一行到s所指向的缓冲区,直到一个终止符\n
或EOF
以enter结束,也就是以\n结束
gets()
函数读取到换行符\n
停止读取,但并不会将\n
读取到字符中,而会在字符串末尾添加\0
字符
可以用空格分割字符串
存在问题:
`gets()`没有绑定检查,字符数组在声明时,已经设定长度为nums,但,`gets()`函数会一直获得字符,存入字符数组,一直到enter结束,而不是nums次,会照成缓冲区溢出错误
解决方法:
使用fgets()
函数避免这种情况——推荐使用这个函数,而不是gets()
语法:char s[nums];
fgets(s,nums,stdin)
getchar()
函数语法:int getchar(void);
**作用:**从屏幕上读取下一个可用字符,并将其返回为一个整数
**注意:**单次只会读取一个单一的字符
输出操作一般没有针对空格、制表符的特殊行为,只有换行符\n
需要特殊对待。
printf()
函数语法:int scanf(const char *format, ...);
**目的:**把输出写入到标准输出流stdout
中,根据提供的format
产生输出
**操作:**获取变量名所在的地址,将从标准输入获得的字符串存储在对应该地址中
补充:
printf
,意思是print formatted
,也就是格式化打印。但如目的中所说,printf()
的功能其实是把字符串写入到stdout
文件缓存,而只有缓存遇到了换行符\n
、缓存满了、缓存被刷新了、stdout关闭等情况,才会触发真正的打印输出。
缓存遇到了换行符
\n
缓存满了
缓存满了会自动清空,所以本质上也是缓存被刷新
缓存被刷新了
- 程序结束时,会自动清空缓冲区
- 使用
fflush()
函数,一般这个函数是用来刷新输出(stdout)缓存的stdout被关闭
所以,平常使用的
printf()
函数,之所以不加\n
数据也会被打印的原因是,程序结束时缓冲区刷新,从而输出缓冲区中的数据会发送到显示设备上被打印。
puts()
函数——自动增加换行符语法:int puts(const char *s)
作用:把字符串s和一个尾随换行符写入到stdout
,并返回打印的字符数
注意:
- puts()函数总会在最后追加一个换行符
\n
- puts()函数会将一个字符串写入到
stdout
中,一直到遇到空字符才结束,但不会将空字符写入。- 如果成功,会返回打印的字符数,所以等于打印的字符串长度加一,那个加一就是最后追加的换行符
\n
putchar()
函数语法:int putchar(int a);
**作用:**把字符输出到屏幕上,并返回相同的字符
注意:单词只会输出一个单一字符
fflush()
函数语法:int fflush(FILE *stream)
EOF
,且设置错误标识符feof
**作用:**强制刷新缓冲区,将缓冲区中的数据立即写到stream
指向的文件(或设备)。
其参数可以为
stdout
,也可以为文件指针,但不可以是stdin
,可能会发生未知错误调用该函数,刷新缓冲区,输出缓冲区中的数据会被传输到设备上打印输出
两种文件类型:
.txt
:纯文本格式存储,最小维护工作,易于阅读,最小安全性,占用更大存储空间.bin
:容纳更多数据,不易读取,更高安全性文件操作:
声明文件
File *fp;
打开/创建——fopen()
函数
作用:创建一个新的文件或者打开一个已有的文件
语法:FILE *fopen(const char *filename, const char *mode);
fopen_s
mode:
r
:只读,打开一个存在的文本文件,如果文件不存在,fopen()
函数返回NULLw
:只写文件,如果文件存在,则将文件截断为0 ,从头写,如果文件不存在则创建一个新文件a
:追加写文件,如果文件不存在则创建一个新文件r+
:读写文件,先读后写,从起始位置上开始写入文件,如果文件不存在,fopen()
函数返回NULLw+
:读写文件,先写后读,如果文件存在,则将文件截断为0 ,从头写。如果文件不存在则创建一个新文件a+
:读写文件。从头开始读,追加的模式写入。如果文件不存在则创建一个新文件rb, wb, ab, rb+, wb+, ab+
注意:
w
模式新建文件,只有路径正确且存在,而文件不存在,才会新建文件夹,也就是说
- 路径存在,文件存在:文件截断为零,重新写入
- 路径存在,文件不存在:创建一个新文件
- 路径不存在,不会新建文件,而是返回
NULL
r+
模式,是读取文件后,从文件指针处开始写入文件
w
,w+
模式,是直接将文件截断为零,重新写入文件
a
,a+
模式,则只会从文件末尾开始追加,无论文件指针在什么位置也就是说,如果想在文件中插入内容,只有
r+
模式能够实现,需要使用fseek()
函数将文件指针偏移到需要插入的位置
rb+
和r+b
是等价的
关闭文件
作用:清空缓存区数据,关闭文件,并释放该文件的所有内存
语法:int fclose(FILE *fp);
EOF
读取
写入
fscanf()
函数**作用:**从文件中读取字符串,遇到第一个空格或者换行符时停止读取
语法:int fscanf(FILE *fp, const char * format, 变量地址)
同
scanf()
函数相比,参数中多了一个fp
文件指针,但其余都一样
fgets()
函数——推荐使用的输入函数作用:从fp
指向的输入流中读取n-1个字符。把读入的字符串复制到缓冲区buf,并在最后追加一个**NULL
**字符来终止字符串。
语法:char *fgets(char *buf, int n, FILE *fp);
如果在读取最后一个字符(第n-1个字符)前,就已经遇到
\n
或者是文件末尾EOF
,则只会返回读取到的字符,包括换行符
结束的三个条件:
- 读取n-1个字符,返回n-1个字符和一个
NULL
字符- 读取到换行符
\n
,返回所有读取的字符,包括换行符- 读取到文章末位
EOF
,返回所有读取的字符
fgetc()
函数**作用:**从fp
指向的输入文件中读取一个字符,
语法:int fgetc(FILE *fp);
EOF
fread()
函数**作用:**从给定流 stream
读取数据到 ptr
所指向的数组中
语法:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *stream);
ptr
:指向一块大小为size_of_elements
* number_of_elements
的内存空间,将要读入的数据存放在这块空间中size_of_elements
:要读取的每个元素的大小,以字节为单位number_of_elements
:元素的个数,每个元素的大小为size_of_element
字节stream
:指向FILE对象的指针,指定了一个输入流fprintf()
函数**作用:**把字符串写入到文件中
语法:int fprintf(FILE *fp, const char * format, ...)
或者,int fprintf(FILE *fp, string str)
fputs()
函数**作用:**把字符串s
写入到fp
所指向的输入流中
语法:int fputs(const char *s, FILE *fp);
EOF
这个输入流,可以是文件流,也可以是
stdout
、stderr
等。
fputc()
函数**作用:**把参数c
写入到fp
指向的输入流中
语法:int fputc(int c, FILE *fp);
EOF
fwrite()
函数**作用:**将ptr
所指向的数组中的数据写入到给定流stream
中
语法:
size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *stream);
ptr
:指向要被写入的元素数组的指针size_of_elements
:要被写入的每个元素的大小,单位为字节number_of_elements
:要被写入的元素的个数,每个元素的大小为size_of_elements
字节stream
:指向FILE对象的指针,指定了一个输出流
标准库定义了cin
、cout
、cerr
、clog
对象
cin
**描述:**是isotream
的一个实例,附属到标准输入设备,通常是键盘。全称为std::cin
。
基础语法:cin >> 变量名 >>[变量2 [>> ...]];
>>
:流提取运算符对
cin
和cout
效率优化代码:std::ios::sync_with_stdio(false); std::cin.tie(0);
另一种使用方法:接收一个字符串,遇到空格、Tab、回车都结束
#include
using namespace std;
int main(){
char a[20];
cin >> a;
cout << a << '\n';
}
cin.get()
函数cin.get(字符变量名)
用来接收字符
#include
using namespace std;
int main(){
char ch;
cin.get(ch)//只能获取一个字符
//ch = cin.get(); //或者这个
cout<
cin.get(字符数组名, 接收字符数)
用来接收一行字符串,包括空格
#include
using namespace std;
int main(){
char a[20];
cin.get(a,20); // 类似于getline。可以输入多个单词,中间空格隔开
cout << a << endl;
}
cin.get()
用于舍弃输入流中的不需要的字符,或者舍弃回车,用来弥补cin.get(字符组名, 接收字符数)
的不足
#include
using namespace std;
int main(){
char a[20];
cin.get(a,20);
cin.get();
cout << a << endl;
cin.get(a,10);
cout << a << endl;
system("pause");
return 0;
}
cin.getline()
函数语法:cin.getline(接收字符数组, 接收个数, 结束字符)
作用:接收一个字符串,包括空格
#include
using namespace std;
int main(){
char m[20];
cin.getline(m, 5);
cout << m << endl;
}
最后一位为
\0
,所以只能看到4个字符输出
cout
**描述:**是iostream
类的一个实例,是行缓冲I/O,连接到标准输出设备,通常是显示屏。全称为std::cout
。
语法:cout << 变量1 [<< 变量2 [<< endl]];
<<
:流插入运算符endl
:end line,输出时插入换行符并刷新流通常认为使用
cout
对象进行输出要比printf
进行输出慢的多,但事实却不一定如此,参考博客C++的cin/cout为什么比C语言的scanf/printf慢,在经过上述2.1.
的优化后,将stdin
和cin
解绑后,其实二者速度已经差不多。
其次,根据网上一些网友的实验,endl
也是拖累cout
速度的一大元凶,因为endl
会在添加换行符的同时刷新输出缓冲区,不断地刷新是cout
效率低下的一个重要原因。(未验证)
cerr
描述:也叫非缓冲标准错误流,是 iostream
类的一个实例,附属到标准输出设备,通常是显示屏。顾名思义,cerr
对象是非缓冲的,也就是说,每个流插入到cerr
都会立刻发送到标准输出设备输出。
语法:cerr << 变量1 [<< 变量2 [<< endl]];
clog
描述:也叫缓冲标准错误流,是 iostream
类的一个实例,附属到标准输出设备,通常是显示屏。
语法:clog << 变量1 [<< 变量2 [<< endl]];
标准库getline()
函数作用:接受一个字符串,可以接受空格并输出
#include
#include
using namespace std;
int main(){
string str;
getline(cin, str);
cout << str << endl;
}
类似于
cin.getline()
gets()
继承C的gets()
getchar()
继承C的getchar()
标准库文件操作:
三个数据类型:
数据类型 | 描述 |
---|---|
ofstream |
该数据类型表示输出文件流,用于创建文件并向文件写入信息。 |
ifstream |
该数据类型表示输入文件流,用于从文件读取信息。 |
fstream |
该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。 |
打开文件—— open()
语法:void open(const char *filename, ios::openmode mode);
filename
:指定要打开的文件的位置和名称mode
:定义文件被打开的模式mode:
ios::app
:追加模式ios::ate
:文件打开后定位到文件末尾ios::in
:打开文件用于读取ios::out
:打开文件用于写入ios::trunc
:如果该文件已经存在,则将文件截断为0关闭文件
语法:void close();
作用:关闭打开的文件流
在C++程序结束时,会自动关闭刷新所有流,释放所有分配的内存,并关闭所有打开的文件
写入文件——输出操作
同cout
一样,使用流插入运算符<<
向文件写入信息,只不过这里使用的对象是ofstream
对象和fstream
对象
读取文件——输入操作
同cin
一样,使用流提取运算符>>
从文件读取信息,只不过这里使用的对象是ifstream
对象和fstream
对象
文件位置指针
seekg
:seek get,istream
的成员函数
seekp
:seek put,ostream
的成员函数
作用:重新定位文件位置指针
语法:(以"get"为例)
seekg(long int n, voctor)
n
:表示偏移字节量voctor
:查找方向
ios::beg
:流的开头ios::cur
:文件指针的当前位置ios::end
:流的末尾比如:
fileObject.seekg( n, ios::cur );
把文件指针从指针所在位置向后偏移n个字节
库控制符 | 作用 |
---|---|
setbase(n) | 以n进制方式输出(n=8,10,16) |
setfill(ch) | 设置字符填充,ch可以是字符常量或字符变量 |
setprecision(n) | 设置输出有效位数为n位 |
setw(n) | 设置字符宽度为n位,只对后一个有影响 |
setiosflags(ios::uppercase) | 以大写字母显示 |
setiosflags(ios::fixed) | 实现对小数点后的数字的控制 |
setiosflags(ios::scientific) | 以科学计数法显示 |
setiosflags(ios::showpoint) | 强制显示小数点 |
setiosflags(ios::showpos) | 强制显示正号 |
setiosflags(ios::left) | 设置输出左对齐 |
setiosflags(ios::right) | 设置输出右对齐 |
resetiosflags(…) | 终止括号中的输出格式 |
补充,这篇文章是广泛阅读了网上关于输入输出流、C语言输入输出、C++输入输出函数各种详解后自己写的笔记,忘了记录学习的网页网址了…只能说十分抱歉,以后会注意的
常用的格式说明符号
转换说明 | 输出 |
---|---|
%d | 有符号 十进制 整数 int |
%f | 十进制 浮点数 float |
%lf | 十进制 浮点数 double |
%c | 字符 char |
%s | 字符串 char* |
%d
:int%hd
:short int%li
:long int%lli
:long long int%u
:unsigned int%lu
:unsigned long int%llu
:unsigned long long int%f
:float,十进制记数法%lf
:double%Lf
:long double%c
:char%s
:string%o
:unsigned int 八进制%[x|X]
:unsigned int 十六进制整数 0[f|F]%[a|A]
:浮点数、十六进制、[p|P]-记数法%[e|E]
:浮点数、[e|E]-记数法%[g|G]
:根据数字自动选择%f
或%[e|E]
%[e|E]
如果获取字符时使用的格式说明符为
%c
,而打印字符时使用的格式说明符为%d
,则会打印获取字符的ASCII码
printf()
的常用修饰符
位置:在%
与字母之间的位置,比如%-f
digit(s)
:字段宽度的最小值
.digit(s)
:精度
%f, %e, %E
,表示小数点右边打印的数字的位数%g, %G
,表示有效数字的最大位数%s
,打印字符的最大位数d
,要打印数字的最小位数.
等价于.0
-
:左对齐
+
:显示正负号
:如果有符号的值为正,则会显示前导空格;为负则显示负号
#
0
:对于所有数字格式,用前导零填充字段宽度
-
和指定精度概念词汇
EOF:End Of File缩写,文件结束的标志,通常值为-1
在fgetc()
和fputc()
函数中,如果操作失败则返回EOF,则,这个时候的EOF代表Error Of File