C++流类输入/输出

在C++中,数据流动的方法一共有四种:

  1. 标准输入输出stdio.h
  2. 在输入输出流类文件iostream.h中定义流对象
  3. 插入运算符:<<
  4. 提取运算符:>>

<<和>>就是我们最常见的cout << endl;或者cin >> str;,我们把cout比作输出设备,如屏幕,cin比作输入设备,如键盘。这些操作符也就在我们一直用的头文件#include <iostream>中。

有一点要说的是,我们在输入一句话中带有空格时,是不能使用cin >> str;的,因为cin在等待读取的过程中,一是遇到回车键返回,二则是遇到空格就返回。所以可以使用另一种方法:cin.get(str,size);

下面只介绍我们常用的文件输入/输出流。

一、文件打开/关闭

1.建立流

流一共有三种:

  • 输入流 ifstream
  • 输出流 ofstream
  • 输入/输出流 fstream

打开一个文件,我们使用open函数

open函数原型:

	void open(char *filename, int mod, int access);
  • filename不用提,大家都懂。

  • mod是文件打开的工作模式。
    对于输入流ifstream,默认是ios::in;对于输出流ofstream,默认是ios::out。

modexplain
ios::app输出时,追加到文件尾部
ios::ate寻找文件尾部
ios::in文件可输入
ios::nocreate不创建,就是说文件不存在时返回失败
ios::noreplace不替换,就是说文件存在时返回失败
ios::out文件可输出
ios::trunc使同名文件被删除
ios::binary二进制形式打开
  • access是打开文件的类型
整型文件类型
0普通文件
1只读文件
2隐藏文件
3系统文件
4备份文件

如:

	out.open("test",ios::out,0);

fstream的两种方式打开,如:

	io.open("test",ios::out | ios::in,0);

当然,前文也说到过,对于ifstream,默认是输入流,ofstream是输出流,所以我们只想打开普通文件时,没有必要这么做。因为我们在执行默认操作时,使用构造函数也是同样的。

	ifstream in("test");

三种文件的方式可以互相借鉴,但是之间并不绝对。如果在目录下没有指定文件,fstream和istream都会执行失败,因为它们没有主动创建文件的步骤。

而ofstream则有判断出该文件不存在,就建立的特性

二、文件读写

首先,我们建立一个txt文件,写入以下内容:

I am a PC!
Hello world!
你好!

1.读

先看读的代码

#include <iostream>
#include <fstream>
using namespace std;

int main(int argc, const char * argv[]) {
    ifstream in("/Users/yucheng/test.txt");
    if(!in)
    {
        cout << "not found" << endl;
        return 0;
    }
    char str[100];
    in >> str;
    cout << str << endl;
    return 0;
}

运行后,猜猜看会显示什么?
·
·
·
·
·
·
答案是

I

我们想象一下,把in看成cin,那么是不是相当于我们在键盘输入的过程呢,在遇到空格或回车停止读取!

所以,我们可以使用

	in.get(str,100);
	//或者
    in.getline(str, 100);

来读取一行
·
·
·

如果要读取全部字符,包括回车符、换行符等。

	char s;
    in.get(s);
    while(!in.eof())
    {
        cout << s;
        in.get(s);
    }

2.写

写主要分为两种,
一是格式化写
二是加在尾端写

#include <iostream>
#include <fstream>
using namespace std;

int main(int argc, const char * argv[]) {
    ofstream out("/Users/yucheng/test.txt");
    if(!out)
    {
        cout << "bcz" << endl;
        return 0;
    }
    char str[100] = "I like this place!\n你好";
    out << str;
    return 0;
}

执行完毕后可发现它默认是格式化书写的

书写的函数接口还有

  • put、get函数,它们是更细节化的char字符类型的获取及写入;
    char ch;
    
    while(!f.eof())
    {
        f.get(ch);
        cout << ch;
    }
    char str[] = "hello world!";
    char * p;
    
    for(p = str ; *p!='\0'; p++)
        f.put(*p);

注意的是,如果你的put字符数量不如文件中原字符数量,容易造成字符混插。

因为在使用get和put函数时,并没有将文件格式化。所以,C++又为我们提供下面两种方法,更为简洁。



  • getline(),get();函数
    其原型是basic_istream& getline(char_type* __s, streamsize __n)

根据其本身意思也能猜到这是读取整行的字符。包括get函数

        f.getline(str,1000);
        cout << str << endl;

所以需要每行每行依次处理字符时,这就很方便。不用判断每行有多少字符。


  • read(char &, length),write(char &, length);
    char str[100];
    f.read(str, 100);
    cout << str << endl;
    char str[100]="hello world!";
    f.write(str, 100);

那么,我们只希望在文档末端加上字符,就需要在构造函数或者open函数里申明ios::app就可以了!

	ofstream out("/Users/yucheng/test.txt",ios::app);
	//或者
	out.open("/Users/yucheng/test.txt",ios::app);

并且,可以根据需要读取的字符串或者整形数字的大小来决定读取位数。

如:

	int num;
	char str[100]="";
	f.read((char *)&num,sizeof(int));
	f.read(str,100);
	cout << num << endl << str << endl;

3、文件指针

文件指针函数有两个:

  • seekg(pos); ——输入文件
  • seekp(pos); ——输出文件

还有两种进阶函数

  • seekg(pos,origin); ——输入文件
  • seekp(pos,origin); ——输出文件

pos就是指针的位置偏移量,origin是起始位置

pos可为正、也可为负。正时往右偏移,负时往左偏移。

origin有以下三种

origin意思
ios::beg文件开头
ios::cur文件当前位置
ios::end文件末端
    f.seekp(3);
    f >> str;
    cout << str;

源文件是:1234567890
输出:4567890

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值