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

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

admin 楼主

2014-1-23 14:57:18

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

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

x
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;
- ], I8 q1 X( _' H8 t
7 J5 [3 G: t0 \! H& J2 R2 q  l  在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:: {) Z5 i8 F8 d. J. q3 I

) M! p7 E" p: M8 E' {& u- m  1、插入器(<<)! g" ~* w& S4 O
( z0 V; y2 n5 A
  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。
* e3 l# M0 G8 J' D, e + d# }+ F0 _' A) s. h" C
  2、析取器(>>)
7 v$ Q6 x* J9 k2 E9 q
' @, M- R) x$ q* ~1 v  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。
8 M/ X3 T8 {+ B2 _
5 O- C2 w, h( G$ S; {  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
: J+ Y2 m) K+ q, P  V2 f/ U1 T1 k 1 `* m" z. H, u; ~3 _( [
  一、打开文件! V1 i$ x5 H6 g4 ]3 Z8 T/ L

; V- z2 I  ~1 I  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:
& s* j8 a7 I, a
0 @" y! T  y! S7 s8 `5 B  void open(const char* filename,int mode,int access);参数:
7 [7 _. O% V& j- L # T$ J* \9 L! K
  filename:  要打开的文件名5 D& D* w6 w  i
, T6 ?0 j# c  L! P
  mode:    要打开文件的方式
% p5 s" ]) c5 H2 s
4 f3 e4 n4 W" ]. _$ j  O  access:   打开文件的属性! r" P% l& y. r8 K$ v

2 L( \' ~2 T3 V# Q6 ~  打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
/ B4 C+ y, X3 k# Y% A ) m, b9 c' T, h- Y! t
  ios::app:   以追加的方式打开文件& d/ w+ H  y. o7 S$ b
8 ]1 }1 j6 C. ?) I1 F+ m
  ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
' I; n, l- {4 {  D0 J
3 F6 f, @: Y2 T* |& M  ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
2 T$ Q2 }1 P2 u/ I& h ; y( o1 i9 @( d! l- j" U5 m
  ios::in:    文件以输入方式打开(文件数据输入到内存)/ e+ p- i: p. |  C! ]# ?9 i" U

+ q5 V& }) J/ A; m8 F5 J9 U  u  ios::out:   文件以输出方式打开(内存数据输出到文件)- F) {$ c3 _2 Z$ _

( [/ i2 A% p( v1 _6 ^6 C  ios::nocreate: 不建立文件,所以文件不存在时打开失败
8 M' f: j! V1 N: k5 t : O3 e' ?" A# N" ]
  ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败+ z7 M. p+ [1 K. |% X7 |# i5 x

" Y; n0 m) S7 M! r# d+ P/ n% m  P  ios::trunc:  如果文件存在,把文件长度设为0
- o( T; g* p. ?8 X
  c& ]$ V5 z" z) q  可以用“或”把以上属性连接起来,如ios::out|ios::binary( |+ _" x9 K0 p# T& x

! o% M7 y1 V  Y7 \" _7 _  打开文件的属性取值是:4 `9 ]& R7 J3 j* U" k- e

2 ^0 H1 ~9 N4 m4 D2 B3 `2 N& P  0:普通文件,打开访问
7 J3 e% x* z& l& c* d + y% E5 |- K5 U- v: u- L
  1:只读文件
: V* j1 z. b; q; j6 g  M
: m' p& E& s) J$ D- q  2:隐含文件6 h" I9 `' k4 ^$ ]8 |8 L( ?

: m) ~8 D3 z$ }# j% n; {  a  4:系统文件; u# W2 {4 \- G% H: p/ o! g
7 a2 @+ |% t8 l: r2 ?& E
  可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。
/ i' K+ g4 J5 T 6 c) m3 [4 x. E) e( G; w
  例如:以二进制输入方式打开文件c:\config.sys
7 w& L+ F. Z! X1 o! p( S. |& U ! |, t# B5 n: x- U9 Y+ I' H
  fstream file1;5 u/ f- U1 I/ o% V% G

; k. N+ b$ G* E& X9 n% k  file1.open("c:\\config.sys",ios::binary|ios::in,0);
! T/ f+ t% S. j# l3 e2 d
" x7 O  m1 C' J' s  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
( s( }9 c' f# V* l; u; F  n 4 }" }6 Y+ q) s1 i
  file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0);7 F( g! |! \5 w+ _* o
( B" x% ^: f8 {  H* Z# q0 b/ A
  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:2 W+ ]( Q0 d. J  n- K
4 ]" ?6 e! P/ k$ `
  fstream file1("c:\\config.sys");  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。/ ?) F2 G0 D5 o- L+ w& r
. _* t- i6 r& L; O) ?
  ifstream file2("c:\\pdos.def");//以输入方式打开文件/ n2 V: @4 n6 Z3 A3 S

$ K, ^3 U0 R9 M  ofstream file3("c:\\x.123");//以输出方式打开文件  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
& q+ y! a# C( t1 B. h7 i- i: ^9 b
( r) h& P( A* g2 U$ E8 D, u  二、关闭文件
) O: f3 K* B  y4 N5 B2 c & W4 I3 L, U3 Z1 z' J
  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。8 s, C5 `* V, a& R5 U+ I: u
% s, s1 Z  c8 r
  三、读写文件* j9 f  o- w7 O) m" a6 d3 j
+ M8 Y5 Y* `" L# z, W' g& Y- `( I
  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式; l  c0 T7 g; o' l( o
# n7 t; I& P0 z3 G
  1、文本文件的读写
& N% ~' t4 e( k- ~1 e6 q 6 b/ c- \  }1 E9 o. w
  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:- J, s* g+ P3 K+ [

% u" r- b% E0 ]# V. |  file2<<"I Love You";//向文件写入字符串"I Love You"
6 _% A7 H- c% x7 [( b) Z
. C0 ~" U  y% A  u& c  int i;
' w9 U- c' O5 ?0 f$ @" j3 W; m( s1 h5 ]- v
. h3 b2 m5 z7 J  file1>>i;//从文件输入一个整数值。
) Z4 K, v+ V# V' F& C1 Z. u
( ?0 k% C3 g  h1 D  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些, v5 T2 s! t0 M' C- @. [* D$ y
/ \4 D# n& _/ p4 k/ e
  操纵符 功能 输入/输出6 a4 o0 O0 P( |; J2 R
# |: p9 v4 `, g
  dec 格式化为十进制数值数据 输入和输出- o  {: S5 @, e: h

+ \4 p+ R- Z8 f8 R. v2 t  endl 输出一个换行符并刷新此流 输出
1 m0 W4 [+ z6 H+ q- g! ^0 w
& f3 x, c" \4 b  ends 输出一个空字符 输出
0 X& m  l6 U6 c. M0 q. }
: Q% R7 P* r8 I) t) v  w( T4 r  hex 格式化为十六进制数值数据 输入和输出
7 G# ]6 f& p( I: R4 t
, u  D# X. s9 D. P) y( F; e* J  oct 格式化为八进制数值数据 输入和输出
6 U1 R, ~+ F$ {( a" y
% [- s/ b) P1 i0 ?* {  setpxecision(int p) 设置浮点数的精度位数 输出
6 Z$ b% P; [- b4 h! D. R6 I7 Y
1 U8 _& z2 y$ L& J3 K, M3 ]: P' H, g% T+ O; Q  比如要把123当作十六进制输出:file1<

' W5 R+ R( Y) c, G! X, ]  2、二进制文件的读写3 X+ s1 h& K2 Z, A

% G, v( l+ t* g6 Q0 a: T' `  ①put()
+ y) z- v5 G9 {$ l9 g
3 }& K2 L& [/ o4 J  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。0 L- {. T2 O+ m4 Q" b3 p2 |
3 L% V# J! D% r& W; t2 j1 I- N* z
  ②get()
9 d; h( W$ n2 O4 D1 G: U) A
% l* Z  k! w  L  get()函数比较灵活,有3种常用的重载形式:
& Q3 V! R' I' y* u+ y5 m! M6 z % s7 T& P9 R9 y8 K; z6 G: L1 R
  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。- r6 B6 l& g, {0 S  e) u0 w
3 o! `/ f4 M1 V
  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。2 F4 [+ d% l/ O' B0 W4 p% ~

) ?' r8 w( A! g) W  还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。例如:1 v8 I2 x- d4 E$ Y2 J

4 ^  \$ |0 f. |( K6 @) M+ l( G  z  file2.get(str1,127,'A'); //从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。4 _  s8 |. E+ D, Z% u

  N! @3 W) \2 y5 P$ r! R- s) G  ③读写数据块' ?/ D8 {+ W5 d
% Q( v: P! x; B  F6 W2 W
  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:
/ ^& e: L/ o. B( U, ]: B* t& z/ I 0 M% x- N& I1 N9 q2 P
  read(unsigned char *buf,int num);' `# g* @7 @* L3 e  M
0 W  o1 [* p8 q$ U
  write(const unsigned char *buf,int num);
; r% L$ S" E" ^2 A" l) y % \4 G) z* A3 ^: i, L% m& ^
  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。
$ n/ o' g; i: _& O/ S9 L , s) ~8 m* a1 H( r( P
  例:& h+ A0 ^) K8 L( Y- Z* r

8 t6 k) Q( |- p( X6 l  unsigned char str1[]="I Love You";  @  `# |" F! t- I. F$ i  H# {

+ X$ F8 [  |$ D  int n[5];
+ C! W2 f) o4 d
! o' k7 s; u2 G  ifstream in("xxx.xxx");8 }5 q4 S7 c! x  R8 K" g
' d0 U8 P' A5 U# \2 k5 z
  ofstream out("yyy.yyy");0 G+ p( _/ C. G( x, H! r  U7 T

) I5 c4 E& O' l  `( P% @( ?  out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中* L! H+ u0 K0 l
/ G8 c/ \; U) K9 m" P: Y- `
  in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换" E. l9 c+ Q0 I
$ w( ?* Q  C. z5 z% u8 e
  in.close();out.close(); 四、检测EOF
5 G/ i6 d5 a8 u0 Q* [' ~ 0 ^# P2 O- Z- o; B& N3 Z- F: B, x
  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();
5 x9 S3 ~9 d" a9 ?6 G* c
- p8 {* t4 R0 p: a: O5 V$ j5 W  例:  if(in.eof()) ShowMessage("已经到达文件尾!");
/ }0 _% x. A3 o% t* N7 q5 }; J . }; m1 a8 k( s
  五、文件定位
- T4 P1 J% x! P+ Q& O
4 k+ C2 x8 x/ P9 e" Z) x  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。它们最通用的形式如下:9 X' A5 f1 E% X" X, G' i
) w, L4 F. f7 [, M: v# X! T8 r
  istream &seekg(streamoff offset,seek_dir origin);
6 R3 A0 [/ n8 L% p1 k8 ]
/ F& g4 R1 W9 v6 i1 H0 d  ostream &seekp(streamoff offset,seek_dir origin);6 C( F2 u% z3 X8 y6 }  X
/ b' t  r  `8 B: \2 m. F+ L1 T
  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
6 U% R* v- ^1 a. C3 q- o6 c ' A  l  k3 Q7 S- d* `; |+ B
  ios::beg:  文件开头8 S2 F! Q- K" Y( n

7 m( j% {+ D* Y) P8 n" w  ios::cur:  文件当前位置: `8 }' `" p  T& N0 C% s
$ }6 v: V  v2 X- I( K
  ios::end:  文件结尾
- ]. z+ n0 R) w% _$ v ; a3 z. H! P7 {9 U* `5 R" a
  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例:1 w; ~0 U: {4 L, R9 ^! C7 Z

( y, ~% R; J  v1 y0 P6 Q7 i  file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节
5 l" Y6 P) g* d" n" O+ L. X- }; \+ ]
+ N5 l" J0 w0 s  file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节

  |9 F4 }* k2 J# U  M% j' {; Q! N
/ ~. X  O! T2 p( W2 n, x$ n
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了