您的位置:首页 > 其它

文件的输入和输出

2014-08-12 09:57 447 查看
一:文件输入输出的三张类型

1. ifstream,由 istream 派生而来,提供读文件的功能。

2. ofstream,由 ostream 派生而来,提供写文件的功能。

3. fstream,由 iostream 派生而来,提供读写同一个文件的功能。

二:文件模式

in  打开文件做读操作

out 打开文件做写操作

app 在每次写之前找到文件尾

ate 打开文件后立即将文件定位在文件尾

trunc 打开文件时清空已存在的文件流

binary 以二进制模式进行 IO 操作

常用文件模式的组合

out 打开文件做写操作,删除文件中已有的数据

out | app 打开文件做写操作,在文件尾写入

out | trunc 与 out 模式相同

in 打开文件做读操作

in | out 打开文件做读、写操作,并定位于文件开头处

in | out | trunc 打开文件做读、写操作,删除文件中已有的数据

例:

outfile.open("precious", ofstream::app);

三 常用操作

#include <iostream>

#include <fstream>

#include <string>

 

int main ()

{
// 打开一个文件并写入
// 会覆盖文件原有内容
// 若没有此文件则会被创建
std::ofstream ofile("test.txt");
// 判断是否文件打开成功
if (ofile.is_open())
{
// 打开文件成功
// 写入数据
ofile << "这是一个简单的文件操作测试。\n";
ofile << "这里写入两行测试用的文本内容看是否存取成功。\n";
// 关闭文件
ofile.close();

 
std::cout << "写入文件成功!" << std::endl;
}
else
{
// 打开文件失败
std::cout << "打开待写入文件失败!" << std::endl;
}

 
std::cout << "-----------------------------------" << std::endl;

 
// 定义用于暂存读取数据的空间
const int BUFF_LEN = 256;
char buffer[BUFF_LEN];
// 打开一个文件并读取
std::ifstream ifile("test.txt");
// 判断是否文件打开成功
if (!ifile.is_open())
{
// 文件打开失败
std::cout << "打开待读取文件失败!" << std::endl;
}
while (!ifile.eof())
{
// 读取一行
ifile.getline(buffer,BUFF_LEN);
std::cout << buffer << std::endl;
}

 
std::cout << "-----------------------------------" << std::endl;

 
// 求指定的文件段长度
long l,m;
std::string filename("test.txt");
// 打开文件
// std::ios::binary 表示用二进制方式打开
std::ifstream file(filename.c_str(), std::ios::in|std::ios::binary);
// 返回当前文件指针的位置
l = file.tellg();
// 将当前文件指针位置移动到文件尾
file.seekg(0, std::ios::end);
// 返回当前文件指针的位置
m = file.tellg();
// 关闭文件
file.close();
// 输出文件大小
std::cout << "size of " << filename;
std::cout << " is " << (m-l) << " bytes.\n";

 
std::cout << "-----------------------------------" << std::endl;

 
// 一次性读取文件内容
char* buff = NULL;
long size;
// 打开文件
// std::ios::binary 表示用二进制方式打开
// std::ios::ate 表示打开后将文件指针移动至文件尾
std::ifstream tfile(filename.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
// 返回当前文件指针的位置
size = tfile.tellg();
// 将当前文件指针位置移动到文件头
tfile.seekg (0, std::ios::beg);
// 分配与文件大小匹配的内存空间
buff = new char[size];
// 读取文件内容
tfile.read (buff, size);
// 关闭文件
tfile.close();

 
std::cout << "the complete file is in a buffer:" << std::endl << buff << std::endl;

 
// 释放内存
delete[] buff;

 
std::cout << "-----------------------------------" << std::endl;

 
system("PAUSE");
return 0;

}

二进制存储简单示例 // 文件操作测试

 

#include <iostream>

#include <fstream>

#include <string>

 

#include <windows.h>

 

#define TYPE_LEN 32 // 长度

 

// 要存储的数据结构

struct SGameType

{
unsigned short ID;// ID
unsigned short Type;// 类型
char Name[TYPE_LEN];// 名字

};

 

// 类型数据

const int gametypecount = 4;

SGameType* gametype = new SGameType[gametypecount];

 

void onInitData(void)

{
memset(gametype,0,sizeof(SGameType)*gametypecount);

 
// 类型数据

 
gametype[0].ID = 1;
gametype[0].Type = 2;
lstrcpy(gametype[0].Name, "植物大战僵尸");

 
gametype[1].ID = 1;
gametype[1].Type = 3;
lstrcpy(gametype[1].Name, "天空生存冒险");

 
gametype[2].ID = 1;
gametype[2].Type = 4;
lstrcpy(gametype[2].Name, "动漫明星大乱斗");

 
gametype[3].ID = 1;
gametype[3].Type = 5;
lstrcpy(gametype[3].Name, "冒险岛");

}

 

int main ()

{
onInitData();

 
char* buff = NULL;
long size;

 
// 打开一个文件并写入
// 会覆盖文件原有内容
// 若没有此文件则会被创建
std::ofstream ofileType("gametype.txt", std::ios::out|std::ios::binary);
if (ofileType.is_open())
{
size = sizeof(SGameType)*gametypecount;
buff = new char[size];
memcpy(buff,gametype,size);
// 写入数据
ofileType.write(buff,size);
// 关闭文件
ofileType.close();

 
delete []buff;
}

 
std::cout << "写入数据成功!" << std::endl;

 
std::cout << "-----------------------------------" << std::endl;

 
// 一次性读取文件内容

 
std::cout << "读出数据:" << std::endl << std::endl;

 
// 读出数据的存储空间
const int __gametypecount = gametypecount;
SGameType* __gametype = new SGameType[__gametypecount];

 
// 读取
std::ifstream tfileType("gametype.txt", std::ios::in|std::ios::binary|std::ios::ate);

 
size = tfileType.tellg();
size--;
tfileType.seekg (0, std::ios::beg);
buff = new char[size];
// 读出数据
tfileType.read (buff, size);
// 关闭文件
tfileType.close();
// 拷贝数据至数据结构
memcpy(__gametype,buff,size);

 
delete[] buff;

 

 
// 输出读取的数据
for(int i=0; i<__gametypecount; i++)
{
std::cout << __gametype[i].Name << std::endl;
}

 
std::cout << "-----------------------------------" << std::endl;

 
system("PAUSE");
return 0;

}

四:成员函数

1.open(): 

void open (const char * filename, openmode mode);

这里filename 是一个字符串,代表要打开的文件名,mode 是以下标志符的一个组合: 

ios::in  为输入(读)而打开文件  

ios::out  为输出(写)而打开文件  

ios::ate  初始位置:文件尾  

ios::app  所有输出附加在文件末尾  

ios::trunc  如果文件已存在则先删除该文件  

ios::binary  二进制方式  

这些标识符可以被组合使用,中间以”或”操作符(|)间隔。例如,如果我们想要以二进制方式打开文件"example.bin" 来写入一些数据,我们可以通过以下方式调用成员函数open()来实现: 

ofstream file;

file.open ("example.bin", ios::out | ios::app | ios::binary); 

ofstream, ifstream 和 fstream 所有这些类的成员函数open 都包含了一个默认打开文件的方式,这三个类的默认方式各不相同: 

类  参数的默认方式  

ofstream  ios::trunc  

ifstream  ios::in  

fstream  ios::out  

2.is_open()

你可以通过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了: 

bool is_open(); 

它返回一个布尔(bool)值,为真(true)代表文件已经被顺利打开,假( false )则相反。 

3.close ()

关闭文件(Closing a file) 当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。关闭文件需要调用成员函数close(),它负责将缓存中的数据排放出来并关闭文件。它的格式很简单: 

void close (); 

这个函数一旦被调用,原先的流对象(stream object)就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程(process)所有访问了。 

4.<<

源代码  运行结果  

    // writing on a text file

    #include <fstream>

 

    int main ()

    {

        std::ofstream examplefile ("example.txt");

        if (examplefile.is_open())

        {

            examplefile << "This is a line.\n";

            examplefile << "This is another line.\n";

            examplefile.close();

        }

        return 0;

    } 

从文件中读入数据也可以用与 cin的使用同样的方法

源代码  运行结果  

    // reading a text file

    #include <iostream>

    #include <fstream>

    #include <stdlib>

 

    int main ()

    {

        char buffer[256];

        std::ifstream examplefile ("example.txt");

        if (! examplefile.is_open())

        {

            cout << "Error opening file"; exit (1);

        }

        while (! examplefile.eof() )

        {

            examplefile.getline (buffer,100);

            cout << buffer << endl;

        }

        return 0;

    } This is a line. 

5.状态标志符的验证

eof () 

它是ifstream 从类 ios 中继承过来的,当到达文件末尾时返回true 。 

bad() 

如果在读写过程中出错,返回 true 。例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候。 

fail() 

除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候。 

eof() 

如果读文件到达文件末尾,返回true。 

good() 

这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false 。 

要想重置以上成员函数所检查的状态标志,你可以使用成员函数clear(),没有参数。 

6.流指针

获得和设置流指针(get and put stream pointers) 所有输入/输出流对象(i/o streams objects)都有至少一个流指针: 

ifstream, 类似istream, 有一个被称为get pointer的指针,指向下一个将被读取的元素。 

ofstream, 类似 ostream, 有一个指针 put pointer ,指向写入下一个元素的位置。 

fstream, 类似 iostream, 同时继承了get 和 put 

我们可以通过使用以下成员函数来读出或配置这些指向流中读写位置的流指针: 

tellg() 和 tellp() 

这两个成员函数不用传入参数,返回pos_type 类型的值(根据ANSI-C++ 标准) ,就是一个整数,代表当前get 流指针的位置 (用tellg) 或 put 流指针的位置(用tellp). 

seekg() 和seekp() 

这对函数分别用来改变流指针get 和put的位置。两个函数都被重载为两种不同的原型: 

seekg ( pos_type position );

seekp ( pos_type position ); 

使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置。要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。 

seekg ( off_type offset, seekdir direction );

seekp ( off_type offset, seekdir direction );

使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是: 

ios::beg  从流开始位置计算的位移  

ios::cur  从流指针当前位置开始计算的位移  

ios::end  从流末尾处开始计算的位移  

流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本模式的文件中某些特殊字符可能被修改。由于这个原因,建议对以文本文件模式打开的文件总是使用seekg 和 seekp的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改。对二进制文件,你可以任意使用这些函数,应该不会有任何意外的行为产生。 

以下例子使用这些函数来获得一个二进制文件的大小: 

源代码  运行结果  

    // obtaining file size

    #include <iostream>

    #include <fstream>

 

    const char * filename = "example.txt";

 

    int main ()

    {

        long l,m;

        std::ifstream file (filename, ios::in|ios::binary);

        l = file.tellg();

        file.seekg (0, ios::end);

        m = file.tellg();

        file.close();

        std::cout << "size of " << filename;

        std::cout << " is " << (m-l) << " bytes.\n";

        return 0;

    } size of example.txt is 40 bytes. 

 7.write()与read()

write ( char * buffer, streamsize size );

read ( char * buffer, streamsize size ); 

这里 buffer 是一块内存的地址,用来存储或读出数据。参数size 是一个整数值。表示读出或写入的字符数。 

其中read函数作用是从文件中读取size个字符,存入buffer中。

而write函数的作用是从buffer中向文件写入size个字符。 

源代码  运行结果  

    // reading binary file

    #include <iostream>

    #include <fstream>

 

    const char * filename = "example.txt";

 

    int main ()

    {

        char * buffer;

        long size;

        std::ifstream file (filename, ios::in|ios::binary|ios::ate);

        size = file.tellg();

        file.seekg (0, ios::beg);

        buffer = new char [size];

        file.read (buffer, size);

        file.close();

 

        std::cout << "the complete file is in a buffer";

 

        delete[] buffer;

        return 0;

    } The complete file is in a buffer 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  文件输入输出