1. C++中各種輸入輸出函數(shù)總結(jié)
與輸入輸出流操作相關(guān)的類關(guān)系
2. 鍵盤輸入輸出函數(shù)
2.1. scanf函數(shù)
-
頭文件
#include"stdio.h"
原型:
int scanf(const char * restrict format,....)
;入口參數(shù):第一個(gè)參數(shù)是格式字符串逊躁,指定輸入格式肌稻,...格式化后的字符串存取地址
返回值:返回值類型為int,如果讀取到文件結(jié)束則返回
EOF
,EOF
為Ctrl+z或者Ctrl+d.其他情況返回int型數(shù)字例如:int res = scanf("%d %d",&a,&b);
如果a,b
都讀取成功,則返回2
采郎;如果a,b
只讀取成功了一個(gè)懂昂,則返回1
介时;如果a,b
都沒有讀取成功,則返回0
.說明:scanf()函數(shù)是C語言庫中的函數(shù)凌彬,但由于C++的向下兼容性沸柔,所以在C++中也可以使用此函數(shù)。次函數(shù)是從標(biāo)準(zhǔn)輸入流stdio(一般是鍵盤輸入)中讀取數(shù)據(jù)铲敛,并將其按照指定格式輸入到制定地址褐澎。
-
用例:
#include <stdio.h> #include <iostream> using namespace std; int main() { int a,b; scanf("%d %d",&a,&b); //注意此處輸入的格式,兩個(gè)輸入數(shù)字之間要以空格分隔開來伐蒋。 printf("%d %d",a,b); }
2.2. cin()類(此類命名空間都在std中工三,無需添加頭文件)。
- 標(biāo)準(zhǔn)流對(duì)象
- 輸入流對(duì)象:cin:用于從鍵盤讀取數(shù)據(jù)先鱼,也可以重定向從文件讀取數(shù)據(jù)
- 輸出流對(duì)象:cout:輸出數(shù)據(jù)到屏幕上俭正,也可以重定向輸出到文件中
- 標(biāo)準(zhǔn)錯(cuò)誤:cerr :默認(rèn)與cout相同
- 標(biāo)準(zhǔn)錯(cuò)誤:clog:默認(rèn)與cout相同
- 判斷輸入流結(jié)束
int x; while(cin>>x){ }
- 如果從文件輸入,讀到文件結(jié)尾算結(jié)束
- 如果從鍵盤輸入型型,則在單獨(dú)一行輸入Ctrl+Z代表輸入流結(jié)束
2.2.1. cin>> 函數(shù)
- 說明:當(dāng)我們從鍵盤輸入時(shí)段审,有一個(gè)緩沖區(qū),當(dāng)輸入結(jié)束時(shí)會(huì)將所輸入的數(shù)據(jù)存到緩沖區(qū)。而cin>>的作用就是從緩沖區(qū)讀數(shù)據(jù)寺枉,所以當(dāng)緩沖區(qū)數(shù)據(jù)本來就有殘留時(shí)抑淫,會(huì)出現(xiàn)讀取出錯(cuò)的問題。值得一提的是:cin函數(shù)遇到空格姥闪、TAB始苇、換行時(shí)讀取結(jié)束。
- 用例:
-
輸入一個(gè)字符串
#include <iostream> using namespace std; void main () { char a[10]; cin>>a; cout<<a<<endl; }
輸入:aaabbbccc
輸出:aaabbbccc
輸入:aaa bbb ccc
輸出:aaa -
輸入一個(gè)數(shù)字
#include <iostream> using namespace std; void main () { int a,b; cin>>a>>b; cout<<a+b<<endl; }
輸入:1回車2回車
輸出:3
-
2.2.2. cin.get()函數(shù)
-
該函數(shù)有三種形式筐喳,分別是
char ch = cin.get(), cin.get(char ch), cin.get(array,length)
cin.get()
和cin.get(char ch)
的用法
這兩個(gè)函數(shù)功能基本一樣催式,都是讀取緩沖區(qū)的一個(gè)字符,遇到換行符結(jié)束避归,但是這兩個(gè)函數(shù)都不會(huì)丟棄緩沖區(qū)里邊的空格和換行符荣月。char ch = cin.get(), cin.get(char ch)
這兩句可得到相同的結(jié)果。
用例:#include <iostream> using namespace std; void main() { char ch1,ch2; cin.get(ch1); ch2 = cin.get(); cout<<ch1<<endl; cout<<ch2<<endl; }
輸入:a換行
輸出:a- cin.get(array,length)
- 這個(gè)函數(shù)是從緩沖區(qū)讀取字符串梳毙,其中array是字符串接受地址哺窄,length-1是字符串長(zhǎng)度,因?yàn)樽詈笠粋€(gè)字符必須存 儲(chǔ)'\0'結(jié)束符账锹,所以此函數(shù)只能接受length-1個(gè)字符萌业。
- 用例:
輸入:abcdefghi#include <iostream> using namespace std; void main() { char ch[5]; cin.get(ch,5); cou<<ch<<endl; }
輸出:abcd
- cin.get(array,length)
2.2.3. cin.getline
函數(shù)
- 原型:
-
cin.getline(char * buf,int length)
:接收一個(gè)長(zhǎng)度為length-1的字符串,包括空格奸柬,遇到換行結(jié)束生年。 -
cin.getline(char * buf,int length,char delim)
:接收一個(gè)長(zhǎng)度為length-1的字符串,包括空格廓奕,或者讀到delim
字符或遇換行符結(jié)束抱婉。
-
#include<iostream>
using namespace std;
int main()
{
char ch[10];
cin.getline(ch,5);
cout<<ch<<endl;
return 0;
}
輸入:aaaaaaaa
輸出:aaaa
- 注意:
- 兩個(gè)函數(shù)都會(huì)自動(dòng)在buf中讀入數(shù)據(jù)的結(jié)尾添加'\0’。
- ‘\n’和delim都不會(huì)被讀入buf,但是會(huì)被從輸入流中取走懂从,
- 如果輸入流中‘\n’或delim之前的字符達(dá)到或者超過bufsize個(gè)授段,就導(dǎo)致讀入出錯(cuò),雖然本次讀入完成番甩,但是以后讀入就會(huì)失敗
2.2.4. 補(bǔ)充說明
- bool eof();判斷輸入流是否結(jié)束
- int peek();返回下一個(gè)字符侵贵,但是不從流中去掉
- istream & putback(char c);將字符ch放回到輸入流
- istream & ignore(int nCount=1,int delim =EOF);從流中刪除最多nCount個(gè)字符,遇到EOF時(shí)結(jié)束
2.2.5. 流操作算子
- 使用流操作算子需要包含頭文件
#include<iomanip>
- 整數(shù)流的基數(shù):流操作算子:dec,oct,hex,setbase
int n = 10;
cout << n << endl;
cout << hex << n << endl;
cout << dec << n << endl;
cout << oct << n << endl;
輸出:
10
a
10
12
- 浮點(diǎn)數(shù)精度流操作算子:precision,setprecision
- 指定輸入浮點(diǎn)數(shù)的有效位數(shù)(非定點(diǎn)方式輸出)
- 指定輸出浮點(diǎn)數(shù)的小數(shù)后的有效位數(shù)(定點(diǎn)防暑輸出)
- 注意:
- 默認(rèn)為非定點(diǎn)輸出
- 設(shè)置定點(diǎn)方式輸出
cout << setiosflags(ios::fixed) << setprecision(6)<<
- 修改為非頂點(diǎn)方式輸出
cout << resetiosflags(ios::fixed) << setprecision(6)<<
cout.precision(5) //是成員函數(shù)
cout << setprecision(5)<< 5.23; //是流操作算子
- 設(shè)置域?qū)?setw,width
- 寬度設(shè)置有效性是一次缘薛,每次讀入和輸出都要設(shè)置寬度
- 使用方式
cin >> setw(4)
或者cin.width(5)
窍育。cout << setw(4)
或者cout.width(5)
- 用戶自定義的流操作算子
ostream & tab(ostream & output){
return output << '\t' ;
}
cout << "aa" << tab << "bb" << endl;
輸出: aa bb
2.2.6. 二進(jìn)制文件讀寫
二進(jìn)制讀文件:
- 函數(shù)原型:
istream & read(char * s,long n);
- 說明:將文件讀指針指向的地方的
n
個(gè)字節(jié)內(nèi)容,讀入到內(nèi)存地址s
宴胧,然后將讀指針向后移動(dòng)n字節(jié)
二進(jìn)制寫入文件
- 函數(shù)原型:
istream & write(const char * s,long n)
- 說明:將內(nèi)存地址s處的n個(gè)字節(jié)內(nèi)容漱抓,寫入到文件中寫指針指向的位置,然后將文件寫指針向后移動(dòng)
n
字節(jié)
例程
#include"iostream"
#include"fstream"
using namespace std;
void test100() {
ofstream fout("some.txt", ios::out | ios::binary);
int x = 120;
fout.write((const char *)(&x), sizeof(int));
fout.close();
ifstream fin("some.txt", ios::in | ios::binary);
int y;
fin.read((char *)& y, sizeof(int));
fin.close();
cout << y << endl;
}
2.3. getline()函數(shù)
原型:
ssize_t getline(char **lineptr,size_t *n,FILE *stream);
(在C語言的GCC擴(kuò)展定義中)getline(cin,string s);
(在C++中)說明:getline不是C語言的庫函數(shù)恕齐,而是GCC的擴(kuò)展定義或者C++庫函數(shù)乞娄,在C語言中和C++中的使用是不同的.
用例1:(在C++中,應(yīng)包含頭文件<string>,讀取字符串包含空格,遇到換行結(jié)束仪或,不包括換行)
例程:
#include <iostream>
using namespace std;
int main()
{
string s;
getline(cin,s);
cout<<s<<endl;
return 0;
}
輸入:abcdefgh換行
輸出:abcdefgh
2.4. gets()函數(shù)
原型:
char *gets(char *buffer);
- 入口參數(shù):從緩沖區(qū)讀取字符串后的寫入地址
- 返回值:讀取成功后返回與入口參數(shù)buffer相同的地址确镊。讀取錯(cuò)誤返回NULL。
- 頭文件:
<string>
- 說明:接收輸入的字符串范删,沒有上限蕾域,但是要保證buffer足夠大,以換行結(jié)束到旦,并將換行符轉(zhuǎn)化為'\0'旨巷。
- 用例:
#include<iostream>
#include<string>
using namespace std;
int main()
{
char ch[10];
gets(ch);
cout<<ch<<endl;
return 0;
}
輸入:abcdefg回車
輸出:abcdefg
2.5. getchar()函數(shù)
- 原型:
int getchar(void);
- 返回值:讀取成功返回用戶輸入的ASCII碼,讀取失敗返回EOF.
- 頭文件:
<string>
或者<stdio.h>
- 說明:接收一個(gè)字符的輸入添忘,包含空格采呐,遇到換行符結(jié)束。
輸入:abc回車#include<iostream> #include<string> using namespace std; int main() { char ch; ch = getchar(); cout<<ch<<endl; return 0; }
輸出:a
3. 文本讀寫函數(shù)
3.1. C++文件讀寫操作
使用方式
#include "fstream"
ofstream ofile //文件寫操作昔汉,內(nèi)存寫入存儲(chǔ)設(shè)備
ifstream ifile //文件讀操作懈万,存儲(chǔ)設(shè)備讀入內(nèi)存
fstream file //文件讀寫操作
ofile.open("filename",mode) //打開文件以及打開模式
if(!ofile){ //判斷文件是否打開成功
cout << "file open error!" << endl;
}
3.1.1. 打開文件
文件操作通過成員函數(shù)open()
實(shí)現(xiàn)打開文件
//open
public member function
void open ( const char * filename,
ios_base::openmode mode = ios_base::in | ios_base::out );
void open(const wchar_t *_Filename,
ios_base::openmode mode= ios_base::in | ios_base::out,
int prot = ios_base::_Openprot);
- 參數(shù):
filename
:操作文件名
mode
:打開文件的方式
prot
:打開文件的屬性 //基本很少用到靶病,在查看資料時(shí),發(fā)現(xiàn)有兩種方式
打開文件的方式在ios類(所以流式I/O的基類)中定義口予,有如下幾種方式:
ios::in 為輸入(讀)而打開文件
ios::out 為輸出(寫)而打開文件
ios::ate 初始位置:文件尾
ios::app 所有輸出附加在文件末尾
ios::trunc 如果文件已存在則先刪除該文件
ios::binary 二進(jìn)制方式
這些方式是能夠進(jìn)行組合使用的娄周,以“或”運(yùn)算(“|”)的方式:例如
ofstream out;
out.open("Hello.txt", ios::in|ios::out|ios::binary) //根據(jù)自己需要進(jìn)行適當(dāng)?shù)倪x取
打開文件的屬性同樣在ios類中也有定義:
0 普通文件,打開操作
1 只讀文件
2 隱含文件
4 系統(tǒng)文件
對(duì)于文件的屬性也可以使用“或”運(yùn)算和“+”進(jìn)行組合使用沪停,這里就不做說明了煤辨。
很多程序中,可能會(huì)碰到ofstream out("Hello.txt"), ifstream in("..."),fstream foi("...")這樣的的使用木张,并沒有顯式的去調(diào)用open()函數(shù)就進(jìn)行文件的操作众辨,直接調(diào)用了其默認(rèn)的打開方式,因?yàn)樵趕tream類的構(gòu)造函數(shù)中調(diào)用了open()函數(shù),并擁有同樣的構(gòu)造函數(shù)舷礼,所以在這里可以直接使用流對(duì)象進(jìn)行文件的操作鹃彻,默認(rèn)方式如下:
ofstream out("...", ios::out);
ifstream in("...", ios::in);
fstream foi("...", ios::in|ios::out);
當(dāng)使用默認(rèn)方式進(jìn)行對(duì)文件的操作時(shí),你可以使用成員函數(shù)is_open()
對(duì)文件是否打開進(jìn)行驗(yàn)證
3.1.2. 關(guān)閉文件
當(dāng)文件讀寫操作完成之后妻献,我們必須將文件關(guān)閉以使文件重新變?yōu)榭稍L問的蛛株。成員函數(shù)close(),它負(fù)責(zé)將緩存中的數(shù)據(jù)排放出來并關(guān)閉文件育拨。這個(gè)函數(shù)一旦被調(diào)用谨履,原先的流對(duì)象就可以被用來打開其它的文件了,這個(gè)文件也就可以重新被其它的進(jìn)程所訪問了熬丧。為防止流對(duì)象被銷毀時(shí)還聯(lián)系著打開的文件笋粟,析構(gòu)函數(shù)將會(huì)自動(dòng)調(diào)用關(guān)閉函數(shù)close。
3.1.3. 文件的讀寫
類ofstream, ifstream 和fstream 是分別從ostream, istream 和iostream 中引申而來的。這就是為什么 fstream 的對(duì)象可以使用其父類的成員來訪問數(shù)據(jù)害捕。
一般來說唆香,我們將使用這些類與同控制臺(tái)(console)交互同樣的成員函數(shù)(cin 和 cout)來進(jìn)行輸入輸出。如下面的例題所示吨艇,我們使用重載的插入操作符<<:
// writing on a text file
#include <fiostream.h>
int main () {
ofstream out("out.txt");
if (out.is_open())
{
out << "This is a line.\n";
out << "This is another line.\n";
out.close();
}
return 0;
}
//結(jié)果: 在out.txt中寫入:
This is a line.
This is another line
// reading binary file
#include <iostream>
#include <fstream.h>
const char * filename = "test.txt";
int main () {
char * buffer;
long size;
ifstream in (filename, ios::in|ios::binary|ios::ate);
size = in.tellg();
in.seekg (0, ios::beg);
buffer = new char [size];
in.read (buffer, size);
in.close();
cout << "the complete file is in a buffer";
delete[] buffer;
return 0;
}
//運(yùn)行結(jié)果:
The complete file is in a buffer
3.1.4. 文件的讀寫指針
ofstream fout("a1.out",ios::app); //以添加方式打開
long location = fout.tellp(); //取得寫指針位置
location = 10L;
fout.seekp(location); //將寫指針移動(dòng)到第十個(gè)字節(jié)處
fout.seekg(location); //將讀指針移動(dòng)到第十個(gè)字節(jié)處
fout.seekp(location,ios:beg); //從頭數(shù)location
fout.seekp(location,ios::cur); //從當(dāng)前位置數(shù)location
fout.seekp(location,ios::end); //從尾部數(shù)location
3.1.5. 用流迭代器讀取寫入文件
#include "vector"
#include "string"
#include "fstream"
#include "iterator"
void practice10_29() {
ifstream files;
vector<string> Str;
files.open("./hello.txt"); //打開文件
istream_iterator<string> in_iter(files); //定義文件輸出流
if (files.is_open()) //如果文件打開成功
while (!files.eof()) { //如果輸入流沒有到末尾
Str.push_back(*in_iter++); //讀取輸入流存儲(chǔ)到內(nèi)存中
}
else {
cout << "open file failed" << endl;
}
files.close();
print(Str);
}
void test10_28() {
vector<string> Str = { "fox","red","banoria" ,"over","begin","man","hello","promise" };
ofstream ofile;
ofile.open("./hello.txt",ios::app);
auto sp = Str.begin();
ostream_iterator<string> out_iter(ofile," ");
if(ofile.is_open())
copy(Str.begin(), Str.end(), out_iter);
ofile.close();
}
4. 注意:
- Linux,Unix下的換行符
'\n'
(ASCII碼:0X0A) - Window下的換行符
'\r\n'
(ASCII碼:0X0D0A,endl是’\n‘)- window下不以二進(jìn)制文件讀寫文件躬它,讀入文件所有
\r\n
會(huì)被自動(dòng)處理為\n
,寫入文件單獨(dú)的\n
會(huì)被自動(dòng)添加\r
- window下不以二進(jìn)制文件讀寫文件躬它,讀入文件所有
- MacOS下的換行符
'\r'
(ASCII碼:0x0d)