文件读写及字符串与整数的相互转换
对于C++中的IO操作,博主nbkyzj的三篇文章概括的特别详细,非常值得参考。这三篇文章是:
C++之标准设备IO操作流
C++之预定义类型IO格式控制
C++之文件IO操作流
下文将会部分参考自这三篇文章。
1. C++之标准设备IO操作流
每种语言系统都会提供IO操作的类库,用于对预定义类型数据进行输入输出的操作。C++也是如此,它是以字节流的形式实现的。在输入操作时,字节流从输入设备(键盘、磁盘)流向内存;在输出操作时,字节流由内存流向输出设备(显示器、打印机);字节流可以是ASCII字符、二进制数据、图形图像、音频视频等信息。文件和字符串也可以看成是有序的字节流,又称为文件流和字符串流。C++的编译系统自带一个面向对象的输入输出软件包,即IO流类库。库中各种类的声明都被包含在相应的头文件中,比如之前经常用到的头文件iostream,其中使用的cincout都是常用的流对象,用于对标准设备的IO操作。还有用于用户文件管理IO操作的fstream头文件(磁盘文件的操作),用于字符串流的IO操作的strstream头文件(内存字符流的操作),以及iomanip头文件用于输入输出的格式控制。
在IO流类库中包含以下几个常用的流类:
ios是抽象基类,类istream和ostream是单继承于ios,而类iostream是通过多继承于类istream和类ostream。ios除了派生出istream和ostream还派生出fstreambase文件流类和strstreambase串流类,而该4类又派生出ifstream、ofstream、istrstream、ostrstream,以及fstream和strstream。
在C++中除了上述提到过的预定义流对象cout和cin外,还有非缓冲标准出错流对象cerr和缓冲标准出错流对象clog,它们都是来自于ostream类的对象,用于输出错信息。cerr和clog之间的不同之处在于cerr是不经过缓冲区直接向显示器输出有关信息,而clog则是先把信息放在缓冲区,缓冲区满后或遇上endl时向显示器输出。
2. C++之文件IO操作流
文件是指存放在外部介质上的数据的集合。大家都知道操作系统是以文件为单位来对数据进行管理的。因此如果你要查找外部介质的数据,则先要按文件名找到指定文件,然后再从文件中读取数据,如果要把数据存入外部介质中,如果没有该文件,则先要建立文件,再向它输入数据。由于文件的内容千变万化,大小各不相同,为了统一处理,在C++中用文件流的形式来处理,文件流是以外存文件为输入输出对象的数据流。输出文件流表示从内存流向外存文件的数据,输入文件流则相反。根据文件中数据的组织形式,文件可分为两类:文本文件和二进制文件。文本文件又称为ASCII文件,它的每个字节存放一个ASCII码,代表一个字符。二进制文件则是把内存中的数据,按照其在内存中的存储形式原样写在磁盘上存放。比如一个整数20000,在内存中占两个字节,而按文本形式输出则占5个字节。因此在以文本形式输出时,一个字节对应一个字符,因而便于字符的输出,缺点则是占用存储空间较多。用二进制形式输出数据,节省了转化时间和存储空间,但不能直接以字符的形式输出。
2.1 文件打开
在C++中对文件进行操作分为以下几个步骤:
1)建立文件流对象;
2)打开或建立文件;
3)进行读写操作;
4)关闭文件。
用于文件IO操作的流类主要有三个fstream(输入输出文件流),ifstream(输入文件流)和ofstream(输出文件流);而这三个类都包含在头文件fstream中,所以程序中对文件进行操作必须包含该头文件。
首先建立流对象,然后使用文件流类的成员函数open打开文件,即把文件流对象和指定的磁盘文件建立关联。成员函数open的一般形式为:
文件流对象.open(文件名,使用方式)
其中文件名可以包括路径(如:e:c++file.txt),如果缺少路径,则默认为当前目录。使用方式则是指文件将被如何打开。以下就是文件的部分使用方式,都是ios基类中的枚举类型的值:
此外打开方式有几个注意点:
1)因为nocreate和noreplace,与系统平台相关密切,所以在C++标准中去掉了对它的支持。
2)每一个打开的文件都有一个文件指针,指针的开始位置由打开方式指定,每次读写都从文件指针的当前位置开始。每读一个字节,指针就后移一个字节。当文件指针移到最后,会遇到文件结束符EOF,此时流对象的成员函数eof的值为非0值,表示文件结束。
3)用in方式打开文件只能用于输入数据,而且该文件必须已经存在。
4)用app方式打开文件,此时文件必须存在,打开时文件指针处于末尾,且该方式只能用于输出。
5)用ate方式打开一个已存在的文件,文件指针自动移到文件末尾,数据可以写入到其中。
如果文件需要用两种或多种方式打开,则用"|"来分隔组合在一起。
除了用open成员函数打开文件,还可以用文件流类的构造函数来打开文件,其参数和默认值与open函数完全相同。比如:文件流类 stream(文件名,使用方法);如果文件打开操作失败,open函数的返回值为0,用构造函数打开的话,流对象的值为0。所以无论用哪一种方式打开文件,都需要在程序中测试文件是否成功打开。
在每次对文件IO操作结束后,都需要把文件关闭。那么就需要用到文件流类的成员函数close,一般调用形式:流对象.close()。关闭实际上就是文件流对象和磁盘文件失去关联。
2.2 文件读写
流类库中的IO操作<<、>>、put、get、getline、read和write都可以用于文件的输入输出。
文件写:
1 #include <iostream> 2 #include <fstream> 3 using namespace std; 4 5 int main() 6 { 7 //打开文件 8 ofstream file("file.txt", ios::out | ios::ate); 9 if (!file) 10 { 11 cout << "不可以打开文件" << endl; 12 exit(1); 13 } 14 15 //写文件 16 file << "hello c++! "; 17 18 char ch; 19 while (cin.get(ch)) 20 { 21 if (ch == ' ') 22 break; 23 file.put(ch); 24 } 25 26 //关闭文件 27 file.close(); 28 29 return 0; 30 }
文件读:
1 #include <iostream> 2 #include <fstream> 3 using namespace std; 4 5 int main() 6 { 7 //打开文件 8 ifstream rfile("file.txt", ios::in); 9 if (!rfile) 10 { 11 cout << "不可以打开文件" << endl; 12 exit(1); 13 } 14 15 //读文件 16 char str[100]; 17 rfile.getline(str, 100);//读到' '终止 18 cout << str << endl; 19 20 char rch; 21 while (rfile.get(rch))//文件指针指向字符‘ ’的下一个 22 { 23 cout.put(rch); 24 } 25 26 cout << endl; 27 28 //关闭文件 29 rfile.close(); 30 31 return 0; 32 }