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 4014 0

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

admin 楼主

2014-1-23 14:57:18

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

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

x
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;% j' H* y4 d) d( v$ E9 B
" I2 |% d6 ^; f% c4 n. O+ A9 y; H
  在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:3 x' @$ ~9 h9 J7 B0 T9 ^

* Y8 G7 z5 u8 x) ]5 |/ j  1、插入器(<<)
7 o# S/ i3 G, c+ w% T
5 m1 r7 B& p. g$ X  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。3 b, H0 ^" l9 u, v

& r' j' d1 S# _3 k2 Y  2、析取器(>>)
+ N# l: A4 O- Y
+ h, ~8 m* [1 ~& Z  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。% X8 e; U5 T- X+ H+ m# n

* @2 a6 a7 `/ u  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。4 _* l  D* z  n1 s/ a- G

5 e. m9 m* D8 B" s" ~, p  一、打开文件
% j% ~  H: _$ R 8 m! Y& t9 X# H. e" D0 `
  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:& q( A  c  ^: G) u. a% d6 j; L* z$ `
' p' V! G" N9 r! ~
  void open(const char* filename,int mode,int access);参数:
/ K* w# g! v; T7 L! Z2 u( | 2 H, u  S( D1 D7 ^/ `8 t
  filename:  要打开的文件名
, d: Y$ i- j8 ?( T 9 y0 X- R8 X! _4 x7 ~5 C  I5 D
  mode:    要打开文件的方式
/ ~7 [2 v- y7 g0 i
+ ], V' H" ~! l8 @$ y  access:   打开文件的属性
) d) T( q( S4 E% w
! [) J, D6 g1 `. s* i  打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
. s  r5 e$ Y/ l7 \ ; m; l( T4 T; Q; p" W; f, ~
  ios::app:   以追加的方式打开文件0 B1 y' x" G/ d: j: ], `, ?/ {7 ]

3 C  t4 v, p, a) d: x' o  X7 k  ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性- ?; ^+ W% \* B- D7 c' c" ^8 k

6 F. i7 N0 U  i1 F- ~/ \  ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
: l  z( P7 w  Z" S$ F / D- Z7 U4 S, l+ Z  E" K
  ios::in:    文件以输入方式打开(文件数据输入到内存)) f: x, t% B; Z3 I- z

, c+ k( j, n5 t, e3 D, K  ios::out:   文件以输出方式打开(内存数据输出到文件)
! u5 g9 \8 K  |7 Q' o0 M: Y, ]/ h " G+ Y0 R' B) S7 v/ x+ ]! ~; i
  ios::nocreate: 不建立文件,所以文件不存在时打开失败
6 P0 k$ O8 }  P# n! w, I' P
- r4 s% U9 H) S* @3 O+ @  ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
8 O' S3 z6 l1 `6 _, D   P" X( [6 D0 e0 u0 H7 _
  ios::trunc:  如果文件存在,把文件长度设为0$ X4 ~+ t+ B# f, d2 u

# o! {1 C7 `. {8 j- r  可以用“或”把以上属性连接起来,如ios::out|ios::binary. b! j% k. k) D# F' W
1 o: g( @6 G: F! d1 d7 H- f+ T
  打开文件的属性取值是:
0 `/ e/ m0 x) [* a+ v# e* _- D ; Z) s  M( B0 y$ L# O
  0:普通文件,打开访问( d  L. J+ I: Y5 ~* o5 R

1 \6 G5 P6 n' O0 w4 U  1:只读文件
6 B6 Y& w3 u. s2 f. O+ {  V
; k) c& p1 d/ a+ K, J  2:隐含文件0 K: a2 `8 f% J3 c2 q

' s0 M1 ?- d4 f) n' G" e5 G  4:系统文件# @" n- T9 a' S& j: ?3 K

) I' T: }& E' G' e* s/ u; ^. o  可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。
& X( y. V, c% F# p0 }2 z
1 U4 N3 R  T% F) X& P  例如:以二进制输入方式打开文件c:\config.sys
; a3 B7 B7 j0 ^' a * P  n% C9 p8 R) `: v( X4 d
  fstream file1;8 W) @  d3 s. r  t" V- `
: h) h) ]4 \$ ]% c, f5 @' F
  file1.open("c:\\config.sys",ios::binary|ios::in,0);9 k! b5 f+ c  Y5 _

+ z8 j' ]0 O4 f. V! y: m! a7 _  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:" O. f" z6 ]* N* X' Q  _, I, B; r

! |5 \- H0 {  ~/ U3 J  file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0);# e5 e) u& W3 }/ Y- n& l
$ I4 J% d$ v4 |( L2 p
  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:2 l. W6 E6 r. {7 w3 b7 b
2 e/ E- m2 c0 d/ J
  fstream file1("c:\\config.sys");  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。9 _* C- n! X1 O9 O: H

% F4 }& _+ r* E/ N  ifstream file2("c:\\pdos.def");//以输入方式打开文件
/ X+ M% h) U) l+ L. l4 z# V" o% b
, f: F$ `+ E/ e$ L* v  ofstream file3("c:\\x.123");//以输出方式打开文件  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
# y; O* b( ~: H  n . T2 m! B  I9 w3 m1 O) N% T6 p& `: \
  二、关闭文件5 k4 V# S1 P- p2 B! ?
  ~! q' ]1 Z( U+ F+ T% G3 b3 Q
  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。
1 |; [+ J0 e) r. J( q
7 A4 {5 Z8 r/ `% {  三、读写文件# R& G6 h, _, L- G! ]/ Z9 I

7 W1 _% O1 {; ]; m% F  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式
, f1 @! }: G! c0 {   i( \- I2 ?" D( Z
  1、文本文件的读写
) L: B; O% @5 {- D/ B, c# W' H' Y " h- p' F0 K- I. }2 O4 w
  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:5 _6 \" _9 q! ]0 P

4 L8 @4 g) E" K. w! N. X) v3 p5 Z" w  file2<<"I Love You";//向文件写入字符串"I Love You"4 \/ }0 |5 h" `' r2 L

* ?0 a. j% b6 d( M4 L: L* y  int i;* g" z, \! Q% }6 b$ m) d( M1 X
, i' C/ R" c# @7 k
  file1>>i;//从文件输入一个整数值。
2 `: }3 @8 M  E, y) A7 ]. T
, J! ?! l! K0 G+ a" K: l4 R% A5 `  U$ n/ X  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些' M. l# ]5 ]  u  c( d$ X$ {
# ?2 s$ e+ g* l- M7 @! ~
  操纵符 功能 输入/输出) F8 o! f; k( l6 F8 k
' F3 ~- H( Y  \/ [, a
  dec 格式化为十进制数值数据 输入和输出
; _& ]$ X# j5 f& h3 O$ ?) V % \3 ]! d( Q. R
  endl 输出一个换行符并刷新此流 输出% y* n& n; n; j. y$ k1 ]

/ Q% i3 Q2 R/ w6 E; E  ends 输出一个空字符 输出4 p! W4 O3 X! Z. e3 D

# @) K: ?( O" J. Q8 @0 v  hex 格式化为十六进制数值数据 输入和输出
# \- P' w2 N( u6 `& j 8 A/ r3 q; C3 ]" I  r0 r
  oct 格式化为八进制数值数据 输入和输出
3 c* `& g1 g6 E, W& c
1 l3 q  O2 n; F  setpxecision(int p) 设置浮点数的精度位数 输出  _$ K3 O+ x( l* Q- m# s5 j  M

3 n) U# R! I5 M1 A  比如要把123当作十六进制输出:file1<
5 M  Q* M- O" D  l% e7 l- \
  2、二进制文件的读写
: q+ }+ u" ]7 U1 p7 H
: o9 s, a" {3 [# p8 ~9 Q. {9 i  ①put()3 L' S4 P" l/ l& z- [/ T5 F
) x! L; ^# Q0 H2 O9 K, e
  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。* w* ]7 O  u3 B" W& n
% t; m' T/ D6 l' _' z
  ②get()0 t8 R% Q5 f/ j3 Z( j

/ C+ d7 v: B& _  get()函数比较灵活,有3种常用的重载形式:
  ^& [* D0 H; ~8 r9 r' ?
  g1 u; X  u! A5 P/ g  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。5 G4 N1 z1 a  ~3 F* ~2 C2 U5 q8 f

" @- j: L8 c3 H: F8 H- H  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。) D+ u: I% f, }8 Q7 F

/ |2 U4 e8 d. e) _2 Q/ b  还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。例如:, N( B/ D4 m4 p# ~/ T4 n# Q3 |( v

3 y& n# \) S; o. t3 g8 j  file2.get(str1,127,'A'); //从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。( p& _( h# p3 T# O6 k9 h/ y3 f+ Y

0 L' A8 s7 q8 ]  ③读写数据块
- {  m* g$ {9 [. P& z/ t
6 B7 I8 a* O' y6 A+ U. A, e  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:1 h# s" Z. W, \: h
0 G& T5 v& J: H8 F( _! S6 b! O0 R
  read(unsigned char *buf,int num);/ ~$ ^. l. H# X0 d" [& z; I; U

  J4 U5 L" C5 c7 b" L  write(const unsigned char *buf,int num);1 Q3 t( r5 g# i* y. _" |& `

8 k% [4 ?! h  i& a* e7 l8 T( a  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。5 [& _* w# y  d4 I( M: h" x& K0 r
- U' o1 N4 u3 j- d
  例:& _% Y% R, t, d) ?* U/ G
" l; R) _) T# d, h* c% g6 j( ^
  unsigned char str1[]="I Love You";  P* C' z. @: n) E" [

) r2 K! |5 F9 N) ^  int n[5];
; b+ q- P! o: [+ I# k * G1 X) J8 S! a, P: F
  ifstream in("xxx.xxx");: l, F+ r' w) C% l
; z; a" M  U& T4 B- _
  ofstream out("yyy.yyy");
" {; a: |8 s# r+ L, z, D9 S   Q% ~: y; c5 _4 B
  out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中2 s8 @$ @; f" u0 M
8 ?' I, f. z" t8 r2 A) j: m
  in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换
7 ?. y/ ~2 ^* k 6 n* y! J0 p! L. S
  in.close();out.close(); 四、检测EOF1 `' s" u4 d0 a* m& P1 z/ D

2 [7 p9 K' q6 F+ U! u' I1 q  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();
/ ^* G6 G: F- k& S
6 l. G! D0 \2 e  例:  if(in.eof()) ShowMessage("已经到达文件尾!");0 R* j0 k1 n0 q. V/ k( G) K

! S" W5 Y( k" l5 X! R  五、文件定位/ Z7 G: I4 \/ c$ l6 p% F" Q

3 }/ S: B+ |5 w( D9 h  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。它们最通用的形式如下:
# V; h8 a2 E1 ^! [
, I$ f# n: e4 q# h& p$ B/ Y3 H' q! o  istream &seekg(streamoff offset,seek_dir origin);
1 |4 m; P0 E8 F+ n) V7 V
7 l7 M5 q1 z1 j7 e& W  ostream &seekp(streamoff offset,seek_dir origin);
) {; j: H$ K' Z( o( u+ G3 z' a $ W6 T+ {; X9 y# E) @" ?+ m2 n( G
  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:6 e$ y5 R' Y. B1 `& s

0 ^3 Q3 V% m: a5 y& p4 n3 @% \  ios::beg:  文件开头
8 Q6 z$ `- @8 X
* z: u4 Z) ?+ \# x- A  ios::cur:  文件当前位置% b' [" }* s  x. C: q
# {6 y8 h6 N3 V7 N
  ios::end:  文件结尾
4 x( W: P& F" x3 t& u. L8 S, ]
' C/ i9 M+ f# Q$ ~  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例:$ {2 ^+ |/ A5 V

" v) b8 ^/ a/ L. r1 w4 _, {! n  file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节
8 ]$ u2 ^; ^! r( P. j
1 `# Y9 B+ X; {8 j; ]  file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节

, Q& w$ j, j6 {6 e% v0 t" `
% G/ z* a3 s* T, V8 _  d$ I
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了