PLM之家精品课程培训,联系电话:18301858168 QQ: 939801026

  • NX二次开培训

    NX二次开培训

    适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术对于老鸟也值得借鉴!.

    NX CAM二次开发培训报名 NX二次开发基础培训报名
  • PLM之家Catia CAA二次开发培训

    Catia二次开发培训

    Catia二次开发的市场大,这方面开发人才少,难度大。所以只要你掌握了开发,那么潜力巨大,随着时间的积累,你必将有所用武之地!

  • PLM之Teamcenter最佳学习方案

    Teamcenter培训

    用户应用基础培训,管理员基础培训,管理员高级培训,二次开发培训应有尽有,只要你感兴趣肯学习,专业多年经验大师级打造!

  • PLM之Tecnomatix制造领域培训

    Tecnomatix培训

    想了解制造领域数字化吗?想了解工厂,生产线设计吗?数字化双胞胎,工业4.0吗?我们的课程虚位以待!

PLM之家PLMHome-国产软件践行者

[转载电子书] ifstream 和 ofstream的用法详细介绍

[复制链接]

2014-1-23 14:57:18 4019 0

admin 发表于 2014-1-23 14:57:18 |阅读模式

admin 楼主

2014-1-23 14:57:18

请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!

您需要 登录 才可以下载或查看,没有账号?注册

x
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;
2 f$ Q" E) S' }& B  @9 ]* g
1 q- Q9 Z  |5 j( V0 \* D7 G  在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:
6 h/ E, {% {4 X9 X
8 @" z- \* ]2 O# y0 C& a! F  1、插入器(<<)% j- M& `) l1 W; Y$ m' H

  F* k  m2 ?, g7 ?# T! G8 F  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。+ _& `! q1 |$ b0 h6 O" F- k
0 t  k) b3 E, B3 j
  2、析取器(>>)
- H0 D4 `/ r+ Z% t2 Q' C ! e  |; h; F" K4 O- _8 u3 D
  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。
+ ]/ ^7 ]6 k% C% l$ i! q" a2 V1 {
; ?  v2 h+ ~% z& C2 i0 F9 T  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。% p- W# X5 c; s4 J8 ?& n: w
1 @8 D, b: L( c/ R  t1 z
  一、打开文件
: P4 |8 z2 _* d- d/ X4 x
, b" [6 b- H. @& x$ |; O  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:
) A1 Z/ ~+ T0 R' y- M
/ r$ _, P$ x% q  void open(const char* filename,int mode,int access);参数:
* w( N" q: y( J8 t4 B& I9 c 6 u- |6 v1 H" S
  filename:  要打开的文件名+ o: e7 }- v" z2 k
. d, J) S0 L2 p" p! w
  mode:    要打开文件的方式
+ A8 e% Y1 H: i( l
- r9 `5 m( r+ q* L) m  access:   打开文件的属性" J( o. v' O2 ~

3 J- {" q3 H/ s; q! _  打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
4 c) `" ]. @: _4 C/ {
1 N' p  [& K6 g5 Y$ k  ios::app:   以追加的方式打开文件+ d! V+ O# V0 ?& h
1 e% T1 u8 S3 s) k2 L
  ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
+ [! a" \, C- D2 _8 t% ~ ' ~. |. W. L, h3 D! n( d$ U0 h& F
  ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文9 f' S8 Y. w  {2 T1 a3 A

- V1 M1 a4 \6 r' C- ]) N  ios::in:    文件以输入方式打开(文件数据输入到内存)
+ b! ?$ R  V  l6 r, D; X3 F * n8 B3 p6 J. u2 r( m
  ios::out:   文件以输出方式打开(内存数据输出到文件)
* l0 a' D7 }  L3 Q3 a' C . B# E- j( M, J  Y( P2 a$ d' v$ a
  ios::nocreate: 不建立文件,所以文件不存在时打开失败+ ^' B# S9 Q1 g: C' @
4 d! F' r& s: I" b  L! t/ e! b
  ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败; k6 g2 Z0 }% [% y. [- J

9 u; r: R# u$ Y% F$ {5 Z  ios::trunc:  如果文件存在,把文件长度设为0
  i. h& Y; m, S' l1 J" a' S; [ % f. G4 ~5 N) _% ^- V
  可以用“或”把以上属性连接起来,如ios::out|ios::binary& E: @9 f5 @! {7 G4 s4 d

# {* |- _0 S5 z6 v! n  打开文件的属性取值是:" l0 z  U! `  y; \

' ^" h% E" W" N: ~8 h$ |2 C  0:普通文件,打开访问
) K' g  {. T4 I: W* \1 F ! S% ~0 W" _2 e  {* K* h
  1:只读文件
$ f  U3 }( C  y ' }" l6 f! n" V. A+ ?5 t! l1 {
  2:隐含文件
8 x7 R7 ~) F0 I: u% {; a - M9 ^! G1 d5 n% B# I+ L8 J3 D% ^2 f
  4:系统文件
" Y7 P- C7 E/ Z! e3 d
8 k& m. |; r- z7 E2 W. W5 r. e  可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。
  n7 T% D. y! W. x: N" z 7 p) ~. j- N8 o) c7 O; R( ]3 |
  例如:以二进制输入方式打开文件c:\config.sys
7 p; }4 A* Z$ {7 Y" _ 7 {6 k& _/ y" h# n7 [+ w
  fstream file1;8 A5 q6 b6 Y) v+ {
; T3 `; Z9 g& y- f8 D
  file1.open("c:\\config.sys",ios::binary|ios::in,0);
( @) w" _/ p# S  E' R0 ^ - ~9 l9 {' T, R7 j- U4 \7 h3 a! ?
  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
+ Y- m9 m# S, L0 E
4 D$ u  \& B- y  file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0);; r2 n, y" y, v
; f0 v% ~' S5 Z! x' f, ^
  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:0 ]7 |' W1 N0 O# O9 k0 A: `- }

+ `7 J" _, X. ^/ @  fstream file1("c:\\config.sys");  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。$ R# u+ M3 X0 u3 ^8 ^
' I# u1 n$ s; r+ I( f. D1 b4 Y
  ifstream file2("c:\\pdos.def");//以输入方式打开文件
$ b. F) b. I8 A6 l# j . z) B; O! B6 @- ?+ ]
  ofstream file3("c:\\x.123");//以输出方式打开文件  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
  E$ D4 O! y" N8 W) `' M 9 N% ^% e6 o6 _
  二、关闭文件9 q$ i2 Z! Q: B0 A! D3 {4 H6 d

8 k) w( Z( q: D0 y% o. ~  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。
5 U, Y  @4 w* O0 }- _; j6 Y
3 N. y/ y) S( x& v5 `1 f, E! i  三、读写文件
: c: W' M! u  O/ F7 m1 M0 g
" }/ Y, n4 Z0 R7 `( f  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式2 ]) l; O. e) s* \

% K2 U* F4 y; I. j  g6 p$ v9 M  T  1、文本文件的读写7 e, S0 p3 l4 [" e& m

" S7 u  T' H0 k% O7 C  B$ S5 H3 F  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:2 o6 y* e/ X' Y5 B4 w9 ?+ {
& e0 b6 ^$ z. ~* t- G
  file2<<"I Love You";//向文件写入字符串"I Love You"
4 x1 m+ c# L' A: g! o/ Q/ E! e
) c- w! |: v% U8 ]) z) `( v1 e  int i;8 a( P6 q/ {5 n0 s# z
! N& @; r, m4 T' v$ v
  file1>>i;//从文件输入一个整数值。
6 b2 E/ ?+ ]& v: g4 ^4 s
5 J; J1 Y& Q7 a" O4 _9 A* z  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些+ c; I1 d- x1 Z

5 a2 ^+ t( D2 |  操纵符 功能 输入/输出
% c$ W  |( ^% B. Y& s
: s. s* [7 q9 `5 _  P& B5 D  dec 格式化为十进制数值数据 输入和输出5 m9 C7 I! T$ ?0 h
+ y# ?! C) L( e9 d; t
  endl 输出一个换行符并刷新此流 输出
/ Q) Q* N/ q/ d3 _ ) {3 \: _! A; f5 @4 ]8 ^
  ends 输出一个空字符 输出% T! Z; ?% q9 V- m# a

0 T) J- |3 T) \) e+ P  hex 格式化为十六进制数值数据 输入和输出
, [0 ^! s; F9 Z, D , x2 V' P$ j& Z$ ~
  oct 格式化为八进制数值数据 输入和输出* H( o4 ?: _$ o# S0 q
- S+ S; T! L" h  X" x) @% g
  setpxecision(int p) 设置浮点数的精度位数 输出) r+ O# U0 i$ F3 H3 B, l

' U/ A7 X7 z& U  比如要把123当作十六进制输出:file1<
6 C" \. N) v7 y- o, U
  2、二进制文件的读写- L9 [( [. o* d3 e& T% M) ?/ N

, L( v4 k* R! M, R0 P  ①put()7 g3 c" Z6 V/ C
4 {( B$ F& ~  y
  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。
8 E  t7 u* i7 x- e) D7 L3 g
7 c9 y& R9 p4 s% C. u9 A9 C- a  ②get()
! z' T, m7 T# j1 `* c% U3 O9 j
' D# m8 D' b; p  get()函数比较灵活,有3种常用的重载形式:
. ~2 h, j3 A: U( J
# R* r# d6 x! ]1 f  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。
* B6 q2 n, X, V+ j7 s) W* l) Z ; Z/ i7 z) S0 m9 Q
  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。$ P) i" ^1 P, n# q% k: S
5 A5 w; K8 F) w5 J: v
  还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。例如:! X. c% y+ t& w; a
2 }. t5 z" B0 a2 M
  file2.get(str1,127,'A'); //从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。
5 ~; F& K. u" M7 V! t
7 N( Z  {9 \" I+ x  ③读写数据块
( }) d# _' O8 s% D) F( F- \- N 4 u( Q4 K. ^) g* l( g% ~. S
  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:2 o' S5 p0 U7 G: O. ]

" H) X! d! C& j  read(unsigned char *buf,int num);/ D: @! {4 w% ], b# v) J

  t$ t! X; e, c2 e+ m1 Q+ t  write(const unsigned char *buf,int num);
/ Y5 p. R; v/ [) g( }
, y7 C* O9 j% X  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。) W* m8 d: V2 Q& m% F
9 F: L  O" b! U1 z/ y
  例:9 z; i; Q" x6 w1 g' j4 R. Y

8 m6 {1 _4 G  g+ ~  [. J4 D  unsigned char str1[]="I Love You";# p8 G* G+ a6 K% x2 C4 V

/ e3 J/ ^, v2 H1 H& O  int n[5];* ^" l( K$ c) `7 L" N  I! T8 g

5 E/ u, _' ^/ H) S) N( W# v  ifstream in("xxx.xxx");
- X6 v' T" p- K7 o( _
6 _  W& a$ M) y, D$ W  ofstream out("yyy.yyy");
+ l2 Z& _- F$ N. k
5 _, q6 I- p5 t8 }0 g% P  out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中
  E& k3 N  c$ Z8 b0 q
+ s( J5 J  T' e. g1 w  in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换  x# q5 {" l' N" \  t& U( j

. U) k% B8 K# t  in.close();out.close(); 四、检测EOF) O3 U9 n; L9 U6 i) n, L7 e8 f1 ]
- H) `+ U/ g6 ?( f4 y: P( K) f+ m& g' M
  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();# T: ^- t; x. A; ~5 J. ]

# q, {; l) |- R: P  例:  if(in.eof()) ShowMessage("已经到达文件尾!");
" T" X  C; \& \2 ~+ ]* p0 T . [. K* n& H& M6 t  W2 L& s
  五、文件定位
+ _* h. z* G. }0 ]4 F; h
5 w# n. u) q6 t; h$ p: z. C  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。它们最通用的形式如下:
! ^! X; C8 z+ X' T$ m/ ^. j
' E' u" Z1 w7 r+ c# ~' {  istream &seekg(streamoff offset,seek_dir origin);
- W7 D6 b- d3 n4 T* z : {. e% Y' N6 ?/ y, I
  ostream &seekp(streamoff offset,seek_dir origin);
: j# {' e% o- J9 w% A; n
, d2 i4 j9 S3 z; g1 q% j& j6 Z  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
4 z# n8 y) p+ X8 p * J4 B; _# |: ?9 j+ u
  ios::beg:  文件开头* _8 \3 g( n: ]8 \+ U! `
& ~0 ~: D& r( y' f6 u
  ios::cur:  文件当前位置6 }5 s, \2 N8 ~4 j: M2 T9 Y
9 a, ]( k" s( Y. p/ \  B5 M
  ios::end:  文件结尾7 e& l2 ]4 b7 n+ j4 H
; h: y- I# h1 a* K, K8 E# C' h
  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例:6 B9 u- p6 j% R+ D  P: P

. B. H# a8 c" N5 s, W5 L: {  file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节
3 w1 v& X; R. W) |0 T4 V - _) D/ [& e) Z1 `! ~$ Y
  file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节
) F( u9 q1 m  u) H/ [% V( O

% E# D% [! ?9 s0 M# k
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 www.diantuankj.com/ doTeam.tech
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 注册

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

    本网站(plmhome.com)为PLM之家工业软件学习官网站

    展示的视频材料全部免费,需要高清和特殊技术支持请联系 QQ: 939801026

    PLM之家NX CAM二次开发专题模块培训报名开始啦

    我知道了