PLM之家精品课程培训

PLM之家精品课程培训

联系电话:18301858168   |   QQ咨询:939801026
NX二次开发培训

NX二次开发培训

UFUN/NXOpen C++和实战案例

适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术。
公众号二维码

关注公众号

点击扫描二维码免费在线高清教程

课程详情
Catia二次开发培训

Catia二次开发培训

市场需求大,掌握核心技术前景广阔

Catia二次开发的市场需求大,人才稀缺。掌握开发技能潜力巨大,随着经验积累将在汽车、航空等领域有所作为。
B站二维码

在线原创B站视频

点击关注工业软件传道士主页

课程详情
Teamcenter培训

Teamcenter培训

全方位培训,从基础应用到高级开发全覆盖

涵盖用户应用基础培训、管理员基础培训、管理员高级培训及二次开发培训等全方位内容,由多年经验讲师打造。
QQ群二维码

加入同行交流

点击扫描二维码加入QQ群

课程详情
×

PLM之家plmhome公众号

课程涵盖: PLM之家所有原创视频

×

关注B站视频

所有高清视频一览无余,全部在线播放学习

×

加入PLM之家QQ群

同行交流,疑问解答,更多互助

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

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

[复制链接]

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

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

admin 楼主

2014-1-23 14:57:18

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

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

x
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;+ P2 \* O8 a* R# ^/ e  a" @

; _: g0 ~/ D* `" d4 k5 \  在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:& L. r4 M6 K. p4 L2 a
; |$ ~- y8 x2 }# |9 E  o! |
  1、插入器(<<)) u6 B$ ^" A2 ^6 B' \
2 Y9 p: S, d% \: N- i7 B
  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。
9 P# m0 F: N  {- M; K6 r! D* V) Z
1 l# u" ?+ ^! S2 Y  2、析取器(>>)
5 a& b# Z) S/ N' v1 [* Q + H+ _# Q+ j3 Z' U3 O5 s
  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。+ P% R/ `. y0 n$ w2 h+ L
$ t( O" a, Q; C" w# A+ T, ~6 U
  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
% s5 M  |% k2 @" R1 y. ^ + @. R8 @" b* w
  一、打开文件2 i1 |% ^. O5 c8 j$ K
& }6 M. M) V: T" r4 W
  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:* b2 P: s- K7 a* f7 ?6 y
2 ^8 p0 ~- Y1 R3 h  K# _
  void open(const char* filename,int mode,int access);参数:
" s: d( l! D8 `8 T0 c " z" F7 q0 b$ {/ X' f  L# {
  filename:  要打开的文件名
5 ^1 q/ C' B- e" C/ E3 ?0 T: }
  e: a! B6 L) E. C  X" ~% D. p4 G; J  mode:    要打开文件的方式
' L2 V, E+ D" q- z: K( Z
8 w& n; O5 v3 ~! _/ |8 p! j% u0 K  access:   打开文件的属性
2 A' a" |/ q  ] * `& X& Q0 E5 I% [% \* d: x
  打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
$ w$ V* J5 Y( U1 a/ R) L 1 t, d) S( ?8 n( V; \! C: L5 }
  ios::app:   以追加的方式打开文件
6 l9 W7 l( e6 W/ t5 x/ A# h1 u# O
8 f" N. Q9 F$ B4 T: p# c6 f  ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性. B) g. [. @1 a& {7 \6 o1 p; c* K7 U
: G0 L& Y% n6 T# }- b) Y
  ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
" k5 V9 r8 t( s4 P( {' n
! r0 X% ~& R( w+ M, _0 o, L  ios::in:    文件以输入方式打开(文件数据输入到内存)+ L# }! z. |& W

1 z& k. M3 L9 k8 T4 P' y  ios::out:   文件以输出方式打开(内存数据输出到文件)( l. f3 ~1 n3 Y

0 S( p) X$ U$ r  ios::nocreate: 不建立文件,所以文件不存在时打开失败
% h4 d( q( d2 ?
% N; H9 ^/ [7 O2 x/ N. Z  I# Q% e  ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
3 b$ Q& G: m( F+ b , n& v; ~' ]7 n% q. y
  ios::trunc:  如果文件存在,把文件长度设为0
/ G$ _7 f1 d3 h5 J$ K3 e; h4 { * B  R* Q$ d( x5 |" D
  可以用“或”把以上属性连接起来,如ios::out|ios::binary
0 z$ p' x/ P4 N4 c- o! y
% ?1 H( i+ R- v* C  打开文件的属性取值是:* L. @- `7 b  ]& c# w
" I/ ^* C1 X" l2 p9 H" {
  0:普通文件,打开访问4 {* S1 m4 ?. _/ i: l* U8 O

, x* `1 \% D8 D3 v1 K+ `: I2 |  1:只读文件  f( t: v9 {- E0 A

9 a5 |" ~/ t* J4 z  2:隐含文件+ ~7 B. g0 p$ [6 i2 p& W) Z
- Z$ n4 k( {' l1 y
  4:系统文件
( a- W- b0 h9 o. b- z3 f- V
, D( T! f+ J% j1 c/ b  _) z  可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。0 n9 ~3 p; S% b  Q

; O' c1 ?/ P2 `+ }  例如:以二进制输入方式打开文件c:\config.sys, E0 `$ O$ `( `; T/ A- R$ n+ v: N
/ {: I' c6 N7 X9 h; x
  fstream file1;
, u4 H3 P! W* u, D9 e  q" A/ B 1 n  G7 y5 O7 {) v, D+ \
  file1.open("c:\\config.sys",ios::binary|ios::in,0);
0 _1 r5 |" A% a8 ^ 9 h  I& z  F9 R, R4 y, R; ?
  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:- W& s* m0 K6 r% ~
- q# k& V0 a9 Y" P- I
  file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0);
/ O, [. f% C1 H9 S# ?7 x ) S  w4 n1 \0 P6 _' p. O  `
  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:
, O5 p6 Z5 z. Z$ A: w0 W# K 1 L( ]% b6 _/ d& S
  fstream file1("c:\\config.sys");  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。
; P  ?* Y4 c. s. z0 N 3 t+ {4 j& J8 e" D! @* e
  ifstream file2("c:\\pdos.def");//以输入方式打开文件
8 A; R" `5 Q6 ]6 l  M 3 a1 v$ ?" R4 u) @& E9 Z& }" W0 W
  ofstream file3("c:\\x.123");//以输出方式打开文件  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
, C! `/ a2 t' l0 Q
8 j( {: b# t; \# o* F8 p, u  二、关闭文件
1 p# `# C) n% V1 _/ V, W2 ~ - Q* z( i+ K$ ?4 }
  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。" O% N; S1 J, \# n) ]
5 r' e# C' }* S% }9 k
  三、读写文件, c* |% `& p! y0 V
- F0 G* W  y4 K) u6 P" j
  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式
! Q" v: T0 Q( n 4 Q. R3 \# t+ Z& V9 t( N
  1、文本文件的读写
- Y. ~2 L# N4 p, v( O, S
' g% t% y  O6 b0 r" \# v  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:8 i7 q" {0 D- L! b1 V+ U
) v) H% |8 M" f2 o9 g
  file2<<"I Love You";//向文件写入字符串"I Love You"( I6 x6 D, O3 s8 A; N6 A1 b" B
) [/ j5 `6 p! K1 x! i: W
  int i;; u6 R' L3 V* O% N$ O( f3 ^7 d+ m; C

6 R( ]1 l8 h2 n1 F4 M! _  Q9 |  file1>>i;//从文件输入一个整数值。
: [8 _  W5 P0 Q/ X# d" ]- T# K7 v / F5 u% t/ s' I# R3 O& s6 S
  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些
- _; n. w- ]* w/ Q1 k! M. m7 Y3 X
! w- m' U- w+ ^+ M  操纵符 功能 输入/输出
2 u* v& R% `% h- w+ }- z1 H7 _ . f4 @9 y. j5 X+ r. u
  dec 格式化为十进制数值数据 输入和输出4 h9 S  \9 r- Z  N8 W- P
; M7 @  V5 a* \2 A
  endl 输出一个换行符并刷新此流 输出
- T% B+ X3 I# |; ]
5 K$ X; S) u- A/ Q  ends 输出一个空字符 输出
# d& ^+ ^! K3 ]# t# T' z9 k0 H% I7 k
$ S) j/ g" l& C5 X- Q  hex 格式化为十六进制数值数据 输入和输出! X4 r, X3 j( i1 q
: F( P, P* f' O8 R4 d" V+ u
  oct 格式化为八进制数值数据 输入和输出
( l4 A, f% E5 y1 I- X; v + z( U9 ?! h; P3 \3 |  C( U& @
  setpxecision(int p) 设置浮点数的精度位数 输出7 C# b& C3 p/ y# w
0 }  ^$ f  G$ s7 P6 d" w! P
  比如要把123当作十六进制输出:file1<
. i2 T! @6 v5 P/ o
  2、二进制文件的读写8 l- z8 M2 u4 U1 I4 k6 l$ j, e
! _9 ^  q$ a$ L( T. o: N6 g
  ①put()' w) X. m' t5 l- x! {
& a9 h+ A2 f% T; V" `# i, E, m
  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。; U# H- V3 d5 Q

6 A$ r! ^) O3 O( J% ~4 C( }* O0 i  ②get()4 R( G4 K* f: s& B) l

; P4 I0 f$ p: \2 M, r, N0 U  get()函数比较灵活,有3种常用的重载形式:" Y# l8 q8 X! P% f# ?* e
- a# q8 @$ n1 T1 U
  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。' A+ A' B' T/ Z

6 V5 R' f- ~; X* E1 ^6 N  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。
! w0 H, p( d$ J . a: ]: v8 ^0 X. o4 K% D# w9 g
  还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。例如:1 s5 [$ m: ^8 s% C6 B) K8 v

3 u2 x3 p) B, R5 G. ?9 c  file2.get(str1,127,'A'); //从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。' x7 e8 k# Z5 Y0 A3 O  h( h

5 L4 H% g- @! ?( |- l  ③读写数据块7 s; ?. w9 \5 S# ~
! x8 N! B* }0 {- h' c
  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:' `& @# [5 Q( G4 I& R& F

9 J' Q5 H: P/ U4 q  C1 s' y" z; {  read(unsigned char *buf,int num);
5 B: c1 Z+ G5 J9 [$ O
1 T5 a- _; W; j  write(const unsigned char *buf,int num);
! k* Y/ R  f! ^% K9 s' H 6 e7 ~$ a& u2 u
  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。) p; l! l8 Q& o3 j4 k
8 T& L' h; |4 o; m7 g- ~+ r
  例:
; T4 A9 M, U; a% Z& V . L  D( [* I7 }- _, F
  unsigned char str1[]="I Love You";% X2 ^8 L+ P; R2 e# H
1 J5 r* S2 u( W8 Y
  int n[5];$ @2 X3 _/ L  Q1 O5 O2 Z( |/ ~: ^
& C* V( a% w# O! s# N/ J) j) Z) n) a8 l
  ifstream in("xxx.xxx");8 a! N$ g5 J* ?8 F
. H" q* j" e9 F8 E9 g
  ofstream out("yyy.yyy");# h+ B0 K* m5 Q( s. d0 G7 X0 f

* x" v* [9 c" r/ d1 d0 L3 L: }  out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中
- [6 B+ r, V' F  y# d( F/ n 3 @6 g4 z8 ~7 L( c" x
  in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换
( j8 v: I9 w, f( ^5 t9 s5 x/ [1 m& N& k
1 x& [% R2 L+ I9 z  in.close();out.close(); 四、检测EOF$ _: n" S' \3 ?  n1 J# x7 P

+ t, W# E8 P3 x$ T; v% l  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();8 B, z: @3 h! r1 d
* {% X. ^1 v, f, g& N  a, H% u9 n
  例:  if(in.eof()) ShowMessage("已经到达文件尾!");
: i4 b4 P8 ~: ?( h 3 Y$ Y1 |) C2 n( h4 |, G5 k% a5 H( n; Q
  五、文件定位) P# y, X, b3 r# w2 H' l* k
- [1 j' C* p8 t
  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。它们最通用的形式如下:
8 k2 j$ l* Y- d! ?
. H# W5 M& G  I1 {( P/ J  istream &seekg(streamoff offset,seek_dir origin);0 w5 n; f0 ~! r3 }. e) ?

- K9 B) K( f. N0 r7 ?9 P  ostream &seekp(streamoff offset,seek_dir origin);
3 M/ _5 u2 z1 o& S : D7 r" d2 k! Z1 \$ B
  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:6 _4 E  S3 E( Q& K% {

' W/ i, W+ m! R9 ?. }  ios::beg:  文件开头2 K% k* `1 S0 X) G' m3 t1 t- k

8 x- U' N5 ]6 ^  G2 k  ~; {9 o$ |  ios::cur:  文件当前位置
- n# f$ v+ Z  P1 g! u8 Q7 ^; T
3 N( x2 o. k: _6 B  ios::end:  文件结尾# l/ c$ p$ h, c+ O1 ]  k3 S4 t2 d

. J2 }+ e; {* L3 _3 Z  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例:
7 E6 D2 ?: P% s2 o, }/ M4 Z
4 {3 A: c$ R. L9 \& O: J  file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节
; P1 }1 y7 ?7 m! o0 c# |/ O: p& b
  B. B! G" g* O" P- j* F  file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节

$ o, ^# F# E& h' r( @: {; @& J4 ~/ R) [. m0 X6 g1 M
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了