C++文件和流
头文件 :
#include <fstream>
本例中声明的输入流和输出流
ifstream inStream;
ofstream outStream;
要声明使用命名空间using namespace std;
ifstream(读)、ofstream(写)以及fstream(可读可写)非别继承了istream、ostream以及iostream,并且继承了相应的操作。
操作 | 说明 |
---|---|
open() | 打开文件,输出流打开不存在的文件时,会自动创建文件 |
is_open() | 成功打开返回true,否则返回false |
>> | 从已经打开的文件中读出一个值 |
<< | 向已将打开的文件中写入一个值 |
getline() | 从已经打开的文件中读取一行至string对象中 |
eof() | 读到文件尾返回true,否则返回false |
close() | 关闭文件 |
open()消息
在使用outStream.open()时,默认情况下是破坏性的操作,即如果原来存在该文件,会将原文件中的内容删除。
此时可以借助open()的第二个参数,避免上述后果
参数 | 说明 |
---|---|
ios::in | ifstream对象的默认打开方式,非破坏性,读取位置在文件头 |
ios::trunc | 打开文件并删除其内容 |
ios::out | ofstream的默认打开方式 |
ios::app | 输出方式打开,非破坏性,写入位置在文件尾 |
ios::ate | 读或者写,位置在文件尾 |
ios::binary | 二进制方式 |
ios::_Nocreate | 不建立文件,文件不存在时打开失败 |
ios::_Noreplace | 不覆盖文件,所以打开文件时如果文件存在失败 |
参数可以一起使用,比如以二进制方式打开test.bin,并向文件尾写入数据:
outStream.open ("test.bin", ios::out | ios::app | ios::binary);
is_open()消息—防御性编程
打开文件的错误一般有,文件路径错误、路径或文件名拼写错误、文件不存在(istream)
在对文件的任何其他操作之前,总是要测试打开文件是否成功。
可以使用assert(inStream.is_open());
(#include <assert.h>)这种方法直接异常中止了程序,最好使用if()判断inStream.is_open()
返回的bool类型的值。然后正常中止程序。
if(inStream.is_open())
{
cout << "successfully!!" <<endl;
}
else
{
cout << "error!!" <<endl;
return -1;
}
或者
if(!inStream.is_open())//打开失败就退出
{
return -1;
}
close()关闭文件
在不需要使用文件时,及时的关闭文件,下次使用,再次打开,尤其是同时打开多个文件的时候
其他流
函数 | 说明 |
---|---|
good() | 操作正确为true |
fail() | 除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true |
bad() | 如果在读写过程中出错,返回 true |
eof() | 如果读文件到达文件末尾,返回true |
clear() | 重置good()为1 |
Setstate(sBit) | 将状态位置1 |
get(ch) | 将下一个字符读入ch |
seekg(offset,base) | 将读取位置从base处移动offset个字节。base可以是ios::beg(将读取位置从流的开始位置移动offset个字符)、ios::cur(将读取位置从流的当前位置移动offset个字符)、ios::end(将读取位置从流的结束位置移动offset个字符) |
seekp(offset,base) | 将写入位置……(同seekg()) |
tellg() | 返回流内读取位置的偏移量 |
tellp() | 返回流内写入位置的偏移量 |
peek() | 返回流内的下一个字符,但是指针不动(保持未读状态) |
putback(ch) | 修改流,使ch为下一个要读取的字符 |
ignore(n,stopChar) | 跳过n个字符,或者直到遇到stopChar为止(此时n为最大值)。n默认为1,stopChar默认为eof |
例子:文件中有如下内容:
11.1 22.2 33.3 44.4 55.5 66.6 77.7 88.8 99.9
计算并显示每一个数值与平均数之间的差。
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
string inputFileName;
cout << "input fileName :" << endl;
cin >> inputFileName;
ifstream inStream(inputFileName.data());
if(!inStream.is_open()) //文件是否成功打开。否,则退出。
{
return -1;
}
double newValue, sum = 0.0, average = 0.0;
int count = 0;
for (;;)
{
inStream >> newValue;
if (inStream.eof()) //读到文件尾退出循环
{
break;
}
sum += newValue;
count++;
}
if (count > 0)
{
average = sum / count; //计算平均数
}
inStream.clear(); // 清除标志位
inStream.seekg(0, ios::beg); // 移动到文件头
cout << endl;
for (;;) //第二次读取文件
{
inStream >> newValue;
if (inStream.eof()) break;
cout << setw(10) << newValue << " : " <<
setw(10) << newValue - average << endl;
}
inStream.close(); //关闭文件流
return 0;
}
运行结果:
格式操纵符
操纵符 | 说明 |
---|---|
boolalpha | 使用字符串false和true表示输出的布尔值 |
noboolalpha | 使用0和1表示输出的布尔值 |
scientific | 使用科学表示法 |
fixed | 使用定点表示法 |
showpoint | 对整形实数显示小数点和尾部的零 |
noshowpoint | 对整形实数隐藏小数点和尾部的零 |
showpos | 显示正数时带加号 |
noshowpos | 显示正数时不带加号 |
dec | 十进制显示 |
oct | 八进制显示 |
hex | 十六进制显示 |
showbase | 指名显示进制 |
noshowbase | 不指名显示进制 |
uppercase | 十六进制中使用大写的A~F;科学计数法使用大写的E |
nouppercase | 十六进制中使用小写的a~f;科学计数法使用小写的e |
skipws | 跳过输入中的空白 |
noskipws | 不跳过输入中的空白 |
flush | 将流的内容写入屏幕 |
endl | 换行字符并清空流 |
left | 左对齐显示 |
right | 右对齐显示 |
internal | 在符号或进制标识与值之间使用填充字符填充 |
例如:
int i = 17;
cout << showbase
<< oct << i << endl;//八进制显示
<< dec << i << endl;//十进制显示
<< hex << i << endl;//十六进制显示
为了使用要求参量的操纵符,必须包含iomanip库。
操纵符 | 说明 |
---|---|
setprecision(num) | 设置要显示的小数位数为num |
setw(num) | 在宽度为num的字段中显示下一个值 |
setfill(ch) | 将填充字符设置为ch(默认为空格) |
字符串流
istringstream:从字符串中输入
ostringstream:输出到字符串
stringstream:输出或输入
str()
函数可以将字符串流转化为string,或者是相反方向的转换
- strstream.str(s):将字符串流strstream设置为字符串s的副本
- str(strstream):返回一个字符串。