C++IO和文件操作

作者: 帅碧 | 来源:发表于2016-11-16 16:18 被阅读13次

文件

标准的输入输出设备名有哪些?

文件输入类的类名是?

  • Iostream

原理

  • cout是流的对象,它在iostream头文件中作为全局对象定义
    ostream cout(stdout)//标准设备名作为其构造时的参数
    
  • ostream流类对应每个基本数据类型都有友元,它们在iostream中声明:

ostream& operator<<(ostream& dest,char* pSource);
ostream& operator<<(ostream& dest,int source);
ostream& operator<<(ostream& dest,char source);


  1. 分析语句:
cout<<"My name is Jone";
//ostream& operator<<(ostream& dest,char *pSource);

  1. 如果是:
cout<<"this is"<<7
//(cout<<"this is")<<7;
//ostream& operator<<(ostream& dest,int pSource);

  • cin是istream的全局对象.istream流类也有若干个友元;
istream& operator>>(istream& dest,char* pSource);    
istream& operator>>(istream& dest,int source);    
istream& operator>>(istream& dest,char source);

  1. C++的类ostream提供了格式化输出和无格式输出的功能
  • 用流插入运算符输出标准类型的数据;
  • 用成员函数put输出字符;
  • 成员函数write的无格式化输出;
  • 输出十进制、八进制、十六进制格式的整数;
  • 输出各种精度的浮点数、输出强制带有小数点的浮点数,以及用科学计数法和定点计数法表示的浮点数;
  • 输出在指定域宽内对齐的数据;
  • 输出在域宽内用指定字符填充空位的数据;
  • 输出科学计数法和十六进制计数法中的大写字母。
int g=0;
int fun() 
{
    return ++g;
}
int main(int argc, char **argv)
{
    cout<<fun()<<fun()<<fun()<<fun()<<endl;
    return 0;
}
//结果为:
//4321

输出流注意事项

    上例中输出的顺序有如下规律:
    计算顺序: 自右向左
    输出顺序: 自左向右
    cout 在执行时相当于一个函数,而即将输出的4 个fun( ) 函数相当参数,编译器在函数调用时的入栈顺序是从右向左的,所以在指向fun( )函数时,依次从右向左执行,执行完fun( )函数之后,cout输出各个参数返回的值,此时又是从左至右进行输出,所以函数的执行结果为:4321
    

输入流

下面我们要讨论流的输入,这是用流读取运算符(即重载的运算符>>)实现的。

  1. 流读取运算符通常会跳过输人流中的空格、tab键、换行符等等的空白字符,稍后将介绍如何改变这种行为。
  2. 当遇到输入流中的文件结束符时,流读取运算符返回0(false);否则,流读取运算符返回对调用该运算符的对象的引用。
  3. 每个输入流都包含一组用于控制流状态(即格式化、出错状态设置等)的状态位。
  4. 当输入类型有错时,流读取运算符就会设置输人流的failbit状态位;
  5. 如果操作失败则设置badbit状态位,后面会介绍如何在I/O操作后测试这些状态位。
  1. 最重要的输出流
  • ostream
  • ofstream
  1. 重要的输入流类
  • istream
  • ifstream
  1. istream的其他成员
  • ignore
#include<iostream>
using namespace std;
int main()
{
    string s;
    cout<<"请输入一个字符串:";
    //1.忽略输入缓存区中的钱八个字符
    //2.在前八个字符中存在结束字符,那么就忽略
    //输入缓冲区 结束字符 之前的字符

    cin.ignore(8,' ');//设置' '为结束字符
    cin>>s;
    cout<<"string = "<<s<<endl;

    return 0;
}
//结果为
//1.请输入一个字符串:1234567890
//string = 90
//2.请输入一个字符串:12 345
//string = 345

  • putback
#include<iostream>
using namespace std;
int main()
{
    char ch;
    cin.putback('a');//将字符a放入到输入缓存流
    cout<<"请输入一个ch数据:";
    cin>>ch;
    cout<<"ch = "<<ch<<endl;
    return 0;
}
//结果为:
//请输入一个ch数据:ch = a

  • peek
#include<iostream>
using namespace std;
int main()
{
    int i;
    string s;
    //获得输入缓冲区中的第一个字符
    cout<<"start"<<endl;
    char ch=cin.peek();
    cout<<"end"<<endl;
    if(ch>='0'&&ch<='9')
    {
        cin>>i;
        cout<<"int i = "<<i<<endl;
    }
    else
    {
        cin>>s;
        cout<<"string s = "<<s<<endl;
    }
}
//结果为:
//1.start
//123
//end
//int i = 123
//2.start
//asdf
//end
//string s = asdf
//3.start
//1qwr
//end
//int i = 1


  • 调用成员函数read、write可实现无格式输入/输出。
char buffe[] =“HAPPY BIRTHDAY”; cout.write(buffer, 10 ); 

  • 成员函数read把指定个数的字符输入到字符数组中。成员函数gcount统计最后输入的字符个数。
cin.read( buffer, 20 ); //读入20个字符
cout.write( buffer, cin.gcount() ); //输出输入的所有字符

流操作算子

int i=11;
cout<<hex<<i<<endl;//结果为:b(转换为十六进制)
cout<<oct<<i<<endl;//结果为:13(转换为8进制)
cout<<hex<<i<<" "<<dec<<14<<endl;//结果为:b 14
return 0;

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int i=11;
    cout<<hex<<i<<" "<<dec<<14<<endl;
    cout<<setbase(8)<<i<<endl;
    return 0;
}
//结果为:
//b 14
//13

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int i=11;
//  cout<<hex<<i<<endl;//结果为:b(转换为十六进制)
//  cout<<oct<<i<<endl;//结果为:13(转换为8进制)
    cout<<hex<<i<<" "<<dec<<i<<endl;
    cout<<setbase(8)<<i<<endl;
    return 0;
}
//结果为:
//b 11
//13

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int i=11;
    cout<<hex<<i<<" "<<dec<<i<<endl;
    cout<<setbase(16)<<i<<endl;
    return 0;
}
//结果为:
//b 11
//b

  • 设置浮点数精度
  1. 可以用流操纵算子setprecision或成员函数percision控制小数点后面的位数。
  2. 设置了精度以后,该精度对之后所有的输出操作都有效,直到下一次设置精度为止。
  3. 无参数的成员函数percision返回当前设置的精度。
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    double root2=3.14159265;
    for(int places=0;places<=9;places++)
    {
        cout<<setprecision(places)<<root2<<"\n";
    }
    return 0;
}
//结果为:
//3
//3
//3.1
//3.14
//3.142
//3.1416
//3.14159
//3.141593
//3.1415927
//3.14159265

  • 设置域宽
  1. 成员函数ios.width设置当前的域宽(即输入输出的字符数)并返回以前设置的域宽。
  2. 如果显示数据所需的宽度比设置的域宽小,空位用填充字符填充。
    ?3. 如果显示数据所需的宽度比设置的域宽大,显示数据并不会被截断,系统会输出所有位。
  3. 域宽设置仅对下一行流读取或流插入操作有效,在一次操作完成之后,城宽又被置回0
  4. 未对所处理的输出数据提供足够的域宽时,输出数据将按需要的域宽进行输出,有可能产生难以阅读的输出结果。
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int t1[5]={12345,1,3333,22,999};
    int t2[5]={2,22,333,4444,55};
    for(int i=0;i<5;i++)
    {
        cout.width(6);
        cout<<t1[i];
    }
    cout<<endl;
    for(int j=0;j<5;j++)
    {
        cout.width(6);
        cout<<t2[j];
    }
    cout<<endl;
    return 0;
}
//结果为:
//12345     1  3333    22   999
 //   2    22   333  4444    55


#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    char n[30]={0};
    cin.width(5);
    while(cin>>n)
    {
        cout<<"n = "<<n<<endl;
        cin.width(5);
    }
    return 0;
}
//结果为:
//(1)1234
//n = 1234
//(2)12345
//n = 1234
//n = 5
//(3)1234567890123
//n = 1234
//n = 5678
//n = 9012
//n = 3

#include<iostream>
#include<iomanip>
using namespace std;
ostream& tab(ostream& output )
{
    return output<<'\t';
}
int main()
{
    cout<<'a'<<tab<<'b'<<'\t'<<'c'<<endl;
    return 0;
}
//结果为:
//a        b         c

文件指针

验证流状态

bool bad( )//读写的过程中出错,返回true
bool fail( )//读写的过程出错,或者格式读取错误也会返回true
bool eof( //读文件到末尾时,返回true
bool good( )//文件读写正常返回true
//若想重置以上成员函数检查的状态标志,可以使用clear( ) 函数

#include<iostream>
#include<iomanip>
using namespace std;
#include<limits>
int main()
{
    int a;
    int b;
    cin>>a;
    cout<<"a = "<<a<<endl;
    cout<<"cin1 = "<<cin.good()<<endl;
    if(!cin.good())
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
    }
    cout<<"cin2 = "<<cin.good()<<endl;
    cin>>b;
    cout<<"b = "<<b<<endl;
    return 0;
}
//结果为:
//(1)g
//a = 0
//cin1 = 0
//cin2 = 1
//12
//b = 12
//(2)12
//a = 12
//cin1 = 1
//cin2 = 1
//23
//b = 23


文件打开

  1. 使用构造函数打开
创建流对象时直接打开文件
    eg: ofstream ofile(const char *filename, openmode);
    
  1. 使用成员函数open打开文件
    eg: ofstream ofile;
     ofile.open(const char *filename, openmode)
     

openmode文件打开模式

  1. ios::in 输入(读)模式打开文件
  2. ios:: out输出(写)模式打开文件
  3. ios::app追加模式打开文件
  4. ios::trunc若文件已经存在则清空文件的模式打开文件
  5. ios::binary 二进制方式打开文件
  • 这些标识可以单独使用,也可以组合使用,中间用”或“ 运算符 ”|“ 间隔。
fstream file;
file.open(“example”, ios::out | ios::app | ios::binary);

文件类的默认打开方式

打开文件时,没有指定打开模式时,使用默认的打开方式;

  1. ofstream: ios:: out | ios::trunc
  2. ifstream: ios:: in
  3. fstream: ios:: in | ios:: out

对于ifstream 的流对象在打开文件时即使指定的模式中没有显示的标明ios::in 模式,ios::in 标识也一直存在

#include<iomanip>
using namespace std;
#include<fstream>
int main()
{
    ifstream ifile("/home/jiangxiubi/1612/jxb");
    char sztext[20];
    double price;
    ifile>>sztext>>price;
    cout<<sztext<<" "<<price;
    ifile.close()
    /*ofstream ofile("/home/jiangxiubi/1612/jxb");
    ofile<<"pear"<<" "<<4.5;
    ofile.close();*/
    return 0;
}
//结果为:在文件jxb中显示pear 4.5

#include<iostream>
#include<iomanip>
using namespace std;
#include<fstream>
int main()
{
    ifstream ifile("/home/jiangxiubi/1612/jxb1",ios::in|ios::binary);
    char temp[20];
    ifile.read(temp,20);
    cout<<temp<<endl;
    ifile.close();
/*  ofstream ofile("/home/jiangxiubi/1612/jxb1",ios::out|ios::binary);
    char temp[20]="nihao";
    ofile.write(temp,20);
    ofile.close();*/
    return 0;
}


文件关闭

  1. 当文件的读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。关闭文件时需要调用成员函数close( ),它负责将缓存中的数据排放出来并关闭文件。
  2. 这个函数一旦被调用,原来的流对象就可以被用来打开其他的文件了,这个文件也可以重新被其他的进程访问了。
#include<fstream>
fstream file;
file.open(“example”, ios::out | ios::app | ios::binary);
if(file !=NULL) {
    cout<<“open failed”<<endl;
}
//……. 文件操作
file.close();


文件指针

流指针相关函数

  1. tellg( )和 tellp( )
    返回一个pos_type类型,即整数,分别代表当前读指针(get) 和 写指针(put) 的位置
  1. seekg( pos_type position ) 和 seekp( pos_type position )
    流指针被改变为指向文件开始计算的一个绝对位置,传入的参数类型与函数tellg 和 tellp 的返回值类型相同
  1. seekg( offset, seekdir) 和 seekp( offset, seekdir)
    从由参数seekdir 设定的位置开始计算一个位移 offset,其中seekdir的值可以是: ios::beg(流开始的位置),ios::cur(流当前的位置),ios::end(流末尾的位置)
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
    ifstream ifile("/home/jiangxiubi/1612/jxb.txt");
    if(NULL==ifile)
    {
        cout<<"打开文件失败"<<endl;
        return -1;
    }
    //定位函数 -get指针(读指针)
    ifile.seekg(0,ios::end);
    //指针位置函数 -get 指针(读指针)
    cout<<"get point position:"<<ifile.tellg()<<endl;
    ifile.close();
    return 0;
}


extern

extern “ C ”

extern 是c/c++

  • 语言中表明函数或全局变量作用范围的关键字,该关键字告诉编译器此,其声明的函数和变量可以在本模块或其他模块中使用

在c++的环境下使用c

  • 的函数时,通常会出现编译器无法找到 obj 模块中的c 函数定义的问题,从而导致链接失败。这时因为在c++ 中支持函数重载,编译时会将函数名和参数列表连接起来,而c 语言不会,因此会造成链接失败的情况,此时 c 函数就需要使用extern “C “ 来进行链接指定

相关文章

  • C++IO和文件操作

    文件 标准的输入输出设备名有哪些? 文件输入类的类名是? Iostream 流 原理 cout是流的对象,它在io...

  • 文件和目录处理相关

    文件和目录处理相关 题: 考点:文件操作/写入操作; 延伸:目录操作函数,其他文件操作; 文件读写操作 文件系统函...

  • 文件系统(三)文件操作、文件缓存/共享/保护/恢复

    (一)文件操作 VFS 在读写操作之外提供了文件打开和关闭操作。 1、打开操作(open)——负责文件路径名解析和...

  • python012-文件操作

    文件的基本操作 1 文件操作步骤 打开文件 读写等操作 关闭文件 注意:可以只打开和关闭文件,不进行任何读写操作。...

  • Linux文件操作

    文件操作 (Linux文件操作)) [文件|目录] Linux文件操作:为了对文件和目录进程处理,你需要用到系统...

  • day12-课后总结

    json文件和异常处理 1.文件操作 a.打开文件和关闭文件的缩写 说明:打开文件,执行完文件操作相关代码后,会自...

  • linux小命令

    基本文件和目录操作 日常的文件的操作有 文件的copy, move, rename, remove 等操作。1)复...

  • Vim文件操作常用技巧

    Vim文件操作从同时操作多个文件和打开和保存文件两个方面进行总结。 (一)Vim同时操作多个文件 一个文件夹下有v...

  • 2020年4月30日 第七章 文件-2

    第七章 文件-2 7.4 文件和目录操作 文件和目录操作包括:查看文件属性、复制和删除文件、创建和删除目录等1.o...

  • 源码学习 go 语言中的文件操作(下)

    上篇文章分析了文件操作中的打开和读取操作。这篇文章我们来分析一下文章的写入和关闭操作。 写入文件 在讨论写文件操作...

网友评论

本文标题:C++IO和文件操作

本文链接:https://www.haomeiwen.com/subject/vuerpttx.html