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):返回一个字符串。
本文详细介绍了C++中文件和流的操作方法,包括文件的打开、读取、写入等基本操作,以及如何进行防御性编程确保文件操作的安全性。此外还探讨了流的状态检查与控制、格式化输出等高级特性。
2633

被折叠的 条评论
为什么被折叠?



