C++的IO库简介

和文件有关系的输入输出类主要在fstream.h这个头文件中被定义,在这个头文件中主要被定义了三个类,由这三个类控制对文件的各种输入输出操 作,他们分别是ifstream、ofstream、fstream,其中fstream类是由iostream类派生而来,他们之间的继承关系见下图所 示。

由于文件设备并不像显示器屏幕与键盘那样是标准默认设备,所以它在fstream.h头文件中是没有像cout那样预先定义的全局对象,所以我们必须自己定义一个该类的对象,我们要以文件作为设备向文件输出信息(也就是向文件写数据),那么就应该使用ofstream类。

ofstream类的默认构造函数原形为:

ofstream::ofstream(const char *filename,int mode = ios::out,int openprot = filebuf::openprot);

filename:  要打开的文件名
mode:    要打开文件的方式
prot:    打开文件的属性

其中mode和openprot这两个参数的可选项表见下表:

mode属性表
ios::app:   以追加的方式打开文件
ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary:  以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in:    文件以输入方式打开
ios::out:   文件以输出方式打开
ios::trunc:  如果文件存在,把文件长度设为0

可以用“或”把以上属性连接起来,如ios::out|ios::binary。

openprot属性表:

0:普通文件,打开访问
1:只读文件
2:隐含文件
4:系统文件

可以用“或”或者“+”把以上属性连接起来 ,如3或1|2就是以只读和隐含属性打开文件。

示例代码如下

[c-sharp] view plaincopy

#include <fstream>   
using namespace std;   
int main()   
{   
ofstream myfile("c://1.txt",ios::out|ios::trunc,0);   
myfile<<"U love C++"<<endl;  
myfile.close();   
system("pause");  
return 0;   
}

文件使用完后可以使用close成员函数关闭文件。

ofstream::app为追加模式,在使用追加模式的时候同时进行文件状态的判断是一个比较好的习惯。 如下面的代码:

[c-sharp] view plaincopy

#include <iostream>  
#include <fstream>  
using namespace std;  
int main()  
{  
    ofstream myfile("e://1.txt",ofstream::app);  
    if(myfile.fail())  
        {  
            cout << "文件创建失败!"<<endl;  
            exit(-1);  
        }  
    myfile << " Cobing" <<endl;  
    myfile.close();  
    system("pause");  
    return 0;  
}

在定义ifstream和ofstream类对象的时候,我们也可以不指定文件。以后可以通过成员函数open()显式的把一个文件连接到一个类对象上。如下例:

[c-sharp] view plaincopy

  1. #include <iostream>  
    #include <fstream>  
    using namespace std;  
    int main()  
    {  
        ofstream myfile;  
        myfile.open("e://1.txt",ofstream::app);  
        if(myfile.fail())  
            {  
                cout << "文件创建失败!"<<endl;  
                exit(1);  
            }  
        myfile << "Cobing" <<endl;  
        myfile.close();  
        system("pause");  
        return 0;  
    }

下面我们来看一下是如何利用ifstream类对象,将文件中的数据读取出来,然后再输出到标准设备中的例子。

[c-sharp] view plaincopy

#include <iostream>  
#include <fstream>  
#include <string>  
using namespace std;  
int main()  
{  
    ifstream myfile;  
    myfile.open("e://1.txt",ifstream::in);  
    if(myfile.fail())  
        {  
            cout << "文件打开失败!"<<endl;  
            exit(1);  
        }  
    char ch;  
    string content;  
    while(myfile.get(ch))  
    {  
        content+=ch;  
    }  
    myfile.close();  
    cout << content <<endl;  
    system("pause");  
    return 0;  
}

我们利用成员函数get(),逐一的读取文件中的有效字符,get()成员函数会在文件读到默尾 的时候返回假值,所以我们可以利用它的这个特性作为while循环的终止条件,我们同时也在上例中引入了C++风格的字符串类型string,在循环读取 的时候逐一保存到content中。

我们在简单介绍过ofstream类和ifstream类后,我们再来看一下fstream类,fstream类是由iostream派生而来,fstream类对象可以同对文件进行读写操作。

[c-sharp] view plaincopy

  1. #include <iostream>  
    #include <fstream>  
    using namespace std;  
    int main()  
    {  
        fstream myfile;  
        myfile.open("e://1.txt",fstream::out|fstream::app);  
        if(myfile.fail())  
            {  
                cout << "open failed!"<<endl;  
                exit(1);  
            }  
        myfile << "cobing love C++" << endl;  
        myfile.close();  
        myfile.open("e://1.txt",fstream::in);  
        if(myfile.fail())  
        {  
            cout << "open file failed!"<<endl;  
            exit(1);  
        }     
        char ch;  
        while(myfile.get(ch))  
        {  
            cout << ch;  
        }  
        myfile.close();  
        system("pause");  
        return 0;  
    }

由于fstream类可以对文件同时进行读写操作,所以对它的对象进行初始话的时候一定要显式的指定mode和openprot参数。

接下来我们来学习一下串流类的基础知识,什么叫串流类
  简单的理解就是能够控制字符串类型对象进行输入输出的类,C++不光可以支持C++风格的字符串流控制,还可以支持C风格的字符串流控制。

  我们先看看看C++是如何对C风格的字符串流进行控制的,C中的字符串其实也就是字符数组,字符数组内的数据在内存中 的位置的排列是连续的,我们通常用char str[size]或者char *str的方式声明创建C风格字符数组,为了能让字符数组作为设备并提供输入输出操作,C++引入了ostrstream、istrstream、 strstream这三个类,要使用他们创建对象就必须包含strstream.h头文件。
  istrstream类用于执行C风格的串流的输入操作,也就是以字符串数组作为输入设备。
  ostrstream类用于执行C风格的串流的输出操作,也就是一字符串数组作为输出设备。
  strstream类同时可以支持C风格的串流的输入输出操作。

  istrstream类是从istream(输入流类)和strstreambase(字符串流基类)派生而来,ostrstream是从 ostream(输出流类)和strstreambase(字符串流基类)派生而来,strstream则是从iostream(输入输出流类)和和 strstreambase(字符串流基类)派生而来。

串流同样不是标准设备,不会有预先定义好的全局对象,所以不能直接操作,需要通过构造函数创建对象。

类istrstream的构造函数原形如下:
  istrstream::istrstream(const char *str,int size);
  参数1表示字符串数组,而参数2表示数组大小,当size为0时,表示istrstream类对象直接连接到由str所指向的内存空间并以/0结尾的字符串。

[c-sharp] view plaincopy

#include <iostream>  
#include <strstream>  
using namespace std;  
int main()  
{  
    char *name = "key love c++";  
    int arraysize = strlen(name) + 1;  
    istrstream istr(name,arraysize);  
    char temp=‘.‘;  
    istr >> temp;  
    system("pause");  
    return 0;  
}

类ostrstream用于执行C风格的串流的输出,它的构造函数如下所示:
  ostrstream::ostrstream(char *_Ptr,int streamsize,int Mode = ios::out);
  第一个参数是字符数组,第二个是说明数组的大小,第三个参数是指打开方式。

接下来我们继续看一下C++风格的串流控制,C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含sstream.h头文件。
  istringstream类用于执行C++风格的串流的输入操作。
  ostringstream类用于执行C++风格的串流的输出操作。
  stringstream类同时可以支持C++风格的串流的输入输出操作。

istringstream是由一个string对象构造而来,istringstream类从一个string对象读取字符。
  istringstream的构造函数原形如下:
  istringstream::istringstream(string str);

[c-sharp] view plaincopy

  1. #include <iostream>  
    #include <sstream>  
    using namespace std;  
    int main()  
    {  
        istringstream is;  
        is.str("k e y 1");  
        cout << is.str() <<endl;  
        system("pause");  
        return 0;  
    }

ostringstream的构造函数原形如下:
  ostringstream::ostringstream(string str);

[cpp] view plaincopy

#include <iostream>  
#include <sstream>  
#include <string>  
using namespace std;  
int main()  
{  
    ostringstream os;  
    os.put(‘a‘);  
    os.put(‘b‘);  
    os << "ccde";  
    string str = os.str();  
    cout << str << endl;  
    system("pause");  
    return 0;  
}

上例在控制台输出"abccde";

我们通过put()或者左移操作符可以不断向ostr插入单个字符或者是字符串,通过str() 函数返回增长过后的完整字符串数据,但值得注意的一点是,当构造的时候对象内已经存在字符串数据的时候,那么增长操作的时候不会从结尾开始增加,而是修改 原有数据,超出的部分增长。

stringstream的构造函数原形如下:
  stringstream::stringstream(string str);

stringstream类的对象我们还常用它进行string与各种内置类型数据之间的转换。

[cpp] view plaincopy

  1. #include <iostream>  
    #include <sstream>  
    #include <string>  
    using namespace std;  
    int main()  
    {  
        stringstream format_message;  
        int val1=512, val2=1024;  
        string init_str="/nwell done";  
        format_message << "val1:" << val1 << "/n"  
                       << "val2:" << val2;  
        format_message << init_str;  
        string get_message=format_message.str();  
        cout << get_message << endl;   
        system("pause");  
        return 0;  
    }

上例输出:

val1:512

val2: 1024

well done

接下来我们来学习一下输入/输出的状态标志的相关知识,C++中负责的输入/输出的系统包括了关于每一个输入/输出操作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是一个枚举类型(就像open_mode一样),以下便是它包含的值。
goodbit 无错误
eofbit 已到达文件尾
failbit 非致命的输入/输出错误,可挽回
badbit 致命的输入/输出错误,无法挽回

  有两种方法可以获得输入/输出的状态信息。一种方法是通过调用rdstate()函数,它将返回当前状态的错误标记。例如,假如没有任何错误,则rdstate()会返回goodbit.

[cpp] view plaincopy

  1. #include <iostream>  
    using namespace std;  
    int main()  
    {  
        int a;  
        cin >> a;  
        cout << cin.rdstate() << endl;  
        if(cin.rdstate()== istream::goodbit)  
        {  
            cout << "correct!";  
        }  
        if(cin.rdstate() == istream::failbit)  
        {  
            cout << "failed!";  
        }  
        system("pause");  
        return 0;  
    }

上例输出:0 correct!

另一种方法则是使用下面任何一个函数来检测相应的输入/输出状态:
bool bad();
bool eof();
bool fail();
bool good();

[cpp] view plaincopy

  1. #include <iostream>  
    using namespace std;  
    int main()  
    {  
        int a;  
        cin >> a;  
        cout << cin.rdstate() << endl;  
        if(cin.good())  
        {  
            cout << "correct!";  
        }  
        if(cin.fail())  
        {  
            cout << "failed!";  
        }  
        system("pause");  
        return 0;  
    }

如果错误发生,那么流状态既被标记为错误,你必须清除这些错误状态,以使你的程序能正确适当地继续运行。要清除错误状态,需使用clear()函数。此函数带一个参数,它是你将要设为当前状态的标志值。,只要将stream::goodbit作为实参。

[cpp] view plaincopy

  1. #include <iostream>  
    #include <string>  
    using namespace std;  
    int main()  
    {  
        int a;  
        cin >> a;  
        cout << cin.rdstate() << endl;  
        cin.setstate(iostream::failbit);  
        cout << cin.rdstate() << endl;  
        system("pause");  
        return 0;  
    }

输出:0 2 (其中goodbit为0,failbit为2)。

时间: 2024-10-05 05:01:54

C++的IO库简介的相关文章

C++ Primer 读书笔记: 第8章 标准IO库

第8章 标准IO库 8.1 面向对象的标准库 1. IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象.在fstream和sstream里定义的美中类型都是从iostream头文件中定义的相关类型派生而来. 2. 流对象不能复制,因此不能存储在vector容器中 3. 形参或返回类型也不能为流类型.如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用.

[APUE]标准IO库(下)

一.标准IO的效率 对比以下四个程序的用户CPU.系统CPU与时钟时间对比 程序1:系统IO 程序2:标准IO getc版本 程序3:标准IO fgets版本 结果: [注:该表截取自APUE,上表中"表3-1中的最佳时间即<程序1>","表3-1中的单字节时间指的是<程序1>中BUFSIZE为1时运行时间结果",fgetc/fputc版本程序这里没放出] 对于三个标准IO版本的每一个其用户CPU时间都大于最佳read版本,因为每次读一个字符

在UNIX系统下使用IO库程序

在上一篇文章中,我们已经可以在UNIX下编译一个hello world 程序了.今天介绍UNIX系统下,如何在程序中使用IO库. 主体流程分为以下三步:(代码参考的是:<<C++ Primer>>) 第一步:新建文件,并命名为“Progr1.cpp” 第二步:在Progr1.cpp中写好main函数,并使用cin ,cout 这两个IO库函数.代码如下 #include <iostream>//告诉编译器要使用 iostream 库.尖括号里的名字是一个.头文件.程序使

C++ Primer学习总结 第8章 IO库

 第8章 IO库 1.    IO类继承关系: 2.    查询iostream流状态P280-281 V是一个int,当我们输入1, 'r',或Ctrl+z 时的输出分别如下: cin.clear()可以清楚所有的错误位,使good()返回true. 3.    fstream对文件的读写P284 初始创建读入和写出fstream对象之后,把fin和fout完全看成cin和cout处理即可,它们操作几乎没有区别. 4.    对同一个文件同时打开进行读写会出现不可预知的BUG. 对于文件的操作

部分编程库简介

1.MFC 微软基础类库(MicrosoftFoundationClasses)的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数. 2.VFW VFW(Video for Windows)是Microsoft推出的关于数字视频的一个软件开发包,VFW的核心是AVI文件标准. 3.DirectShow DirectShow是微软公司在ActiveMovie和Video for Windows的基础上推出的新一代基于COM(Component Object Mod

读书笔记-APUE第三版-(5)标准IO库

ISO C标准I/O库使用流的概念读写文件.流是对数据传输的抽象,可以把流理解为从起点到终点间的字节序列. 标准I/O库通过维护进程空间内的缓冲区,减少read/write系统调用次数来提高I/O效率.之前介绍的Unbuffered I/O和文件描述符fd打交道,标准I/O则使用FILE指针. typedef struct{ short level;/*缓冲区满程度*/ unsigned flags;/*文件打开状态标志*/ char fd;/*文件描述符*/ unsigned char hol

Node.js websocket 使用 socket.io库实现实时聊天室

认识websocket WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duple).一开始的握手需要借助HTTP请求完成. 其实websocket 并不是很依赖Http协议,它也拥有自己的一套协议机制,但在这里我们需要利用的socket.io 需要依赖到http . 之前用java jsp写过一个聊天,其实实现逻辑并不难,只是大部分时间都用在UI的设计上,其实现原理就是一个基于websocket的通信,要想做一个好的聊天室,我觉得大部

BerkeleyDB库简介

BerkeleyDB库简介 BerkeleyDB(简称为BDB)是一种以key-value为结构的嵌入式数据库引擎: 嵌入式:bdb提供了一系列应用程序接口(API),调用这些接口很简单,应用程序和bdb所提供的库一起编译/链接成为可执行程序: NOSQL:bdb不支持SQL语言,它对数据的管理很简单,bdb数据库包含若干条记录,每条记录由关键字和数据(key-value)两部分构成.数据可以是简单的数据类型,也可以是复杂的数据类型,例如C语言的结构体,bdb对数据类型不做任何解释,完全由程序员

Unix环境之标准IO库

UNIX的文件IO都是针对文件描述符的,而标准IO的操作则是围绕流进行的.当一个流最初被创建时,它并没有定向.若在未定向的流上使用一个多字节IO函数,则将该流的定向设置为宽定向:若在未定向的流上使用一个单字节IO函数,则将该流的定向设置为字节定向. stdio.h定义了三个标准流,stdin.stdout和stderr,分别是标准输入.标准输出和标准出错. 缓冲-- 标准IO库提供缓冲的目的是尽可能减少使用read和write调用的次数.它也对每个IO流自动地进行缓冲管理,从而避免了应用程序需要