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

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

admin 楼主

2014-1-23 14:57:18

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

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

x
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;  j& {. e; m$ W$ N
4 x% b6 V2 C5 q7 i
  在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:
  E& R' \) `  T' ?4 |- ~  B 3 ]% q+ H* k8 B* g: h: C
  1、插入器(<<)
$ [! R0 x$ m/ m+ I & L7 A6 \( H9 ~4 G8 C: X" o
  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。
" E- R0 ~, U8 p; |   w2 ?' \: o  s6 h$ ~
  2、析取器(>>)4 F7 I; I, F! T+ M& [9 o* w

( u5 O  M' {) Q3 y+ ]) a2 g* ~! k0 j  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。
8 P! h% F/ F# `% z; Z# g 0 k% _1 t: z, G
  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
" l( T+ v/ A2 o9 W
$ i, E' D4 e% D  Z/ m  一、打开文件
4 u9 @% p/ v2 F3 x. U1 S5 n 0 u# N6 z# T4 H! X+ B
  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:& z  Y0 p4 t- Q! J* A2 w) k1 b2 C

4 b2 U4 `, U# G  void open(const char* filename,int mode,int access);参数:
; ^# v3 }/ y1 s9 h) B2 l. q & O& x, j. u  T* t. ]! r: [8 ~
  filename:  要打开的文件名
9 ^% |9 {1 O$ T" u# _" d ( {  v7 b6 J0 j- w" [1 j" E2 J
  mode:    要打开文件的方式
' ~6 x+ `# e- s3 O, z
: g. J9 n9 X. q  access:   打开文件的属性
% J) Z3 K# B& F+ B  x' ^
3 n1 `# U: }2 I8 t+ `# @  打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
! w# A: y6 n2 B( H
' \1 h3 J5 a/ p3 Q0 m! D  ios::app:   以追加的方式打开文件
9 Q* p7 o# F) C  V! l 7 j' d; q1 d5 q8 z5 H4 S: {6 i: y2 b
  ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
; s8 K! T9 f1 n# z3 Y3 O) K7 q
8 ]9 v  Z5 ]# ~* k' U. Y  ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文. @- D0 U/ g5 s1 X, X( G' q

$ O, I& \. A+ N% F) g  ios::in:    文件以输入方式打开(文件数据输入到内存)
. ~8 z& ?; u) X3 S, Z
2 {8 ]* [" E1 k1 H+ Y5 G  ios::out:   文件以输出方式打开(内存数据输出到文件)
' ^* h' _$ F5 M' ~7 W" w 1 q% V, A: z3 m2 d: A. U" r
  ios::nocreate: 不建立文件,所以文件不存在时打开失败
7 K7 ~0 D& D: k3 z; o 4 L  `3 T* C1 R2 D' n; w7 X9 d
  ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败/ N  E$ i& G. ?8 Y7 |5 f
5 |; ?9 D; |' C7 V
  ios::trunc:  如果文件存在,把文件长度设为0( Q! E% ^% ^1 L; |
/ }5 p: F% T# }$ M- k
  可以用“或”把以上属性连接起来,如ios::out|ios::binary, k* _+ b" u5 `+ _( G
0 s) p) S( M6 H' {8 }' d+ o. a
  打开文件的属性取值是:4 M! R( P3 Z5 t5 W, o

5 g$ E7 \; m+ O! [  0:普通文件,打开访问
' f: ?3 }: K. f; Q* |- {& `
  Y: p4 E3 i' S0 y! ]8 y- h1 V  1:只读文件1 w0 A$ L4 b5 A4 J4 \" x3 O

, d; x) a1 f1 `' B  2:隐含文件  \$ U+ x! z& I! Z: u: n7 `& d
. V# S7 w) x1 G: V6 P+ d
  4:系统文件
! V+ N& y2 e" P3 a! U: W* ^1 n+ y
) k% B+ V/ G9 o& j' I" R. W  可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。& j: E/ w  q4 N7 l1 q- l
5 G( T7 V0 q9 w& Q* A/ l# P
  例如:以二进制输入方式打开文件c:\config.sys
* W* Z4 @9 G; A8 {7 Z/ ^
+ ~& ~6 e0 u2 u( @  fstream file1;  h3 D7 K0 |0 D

  C- S4 Y& t. n7 C% D# p' p  file1.open("c:\\config.sys",ios::binary|ios::in,0);2 P: x+ [5 w( T0 V$ n: {
% X3 m# _) j: j+ t8 w; u( B
  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
/ H. E+ }9 T% W0 K5 V
  `1 U1 y1 c4 |) p. m  file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0);( c" u' ~5 _$ T
, `$ z9 z8 b2 }! i% \5 o& g
  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:
! ^2 L( M" t0 H2 `5 t& O
9 M; n; u5 w7 [  fstream file1("c:\\config.sys");  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。3 o3 C; T0 c* @5 q

/ Z: Z4 L5 [, S$ |5 T  ifstream file2("c:\\pdos.def");//以输入方式打开文件
& u# s/ Z8 b2 P: _
/ }2 _( \& [2 h4 N  ofstream file3("c:\\x.123");//以输出方式打开文件  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
6 p- p* F/ r; L5 M " Q! ?, Z: C2 \! g
  二、关闭文件& P& \* y( y  Y, F, U, p6 i

0 m& H" `" `' J1 h( S  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。  C/ H3 ]9 N; A8 o* E/ R  a0 Y- @
" a- S9 b& U9 z1 F/ U0 r
  三、读写文件* N7 V! o+ r9 Z4 q- k* h' K' {, j
2 M! t8 Q! o8 ~% p
  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式3 ]! P  k3 y# p& x( J* e
$ s; ^) p, B2 ~4 b5 `: e. x
  1、文本文件的读写
* }+ p$ j+ E0 H
) u: [- G/ X3 U+ m0 `  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:
3 c* B0 O. t: T( `/ B
' T# W3 a2 {* `8 a7 ]( M# K. B  file2<<"I Love You";//向文件写入字符串"I Love You"
- U3 E5 m( W* a- ~
* H, X8 I* N) b. t- J$ |# x  int i;
, z- F/ Z/ T- p4 l& z8 t( r3 f* w + P) F+ c  m. \! B
  file1>>i;//从文件输入一个整数值。
, g& Z& O- S1 ]5 F
% N5 L7 }( `  Q# K3 E  E  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些( k5 a) v" f: j* K# e  x8 |
8 h) S" W5 Q+ b8 E; f+ k7 O9 F" ^
  操纵符 功能 输入/输出
+ y# U( q: Z' z3 }. I( i
; g; N% X3 p/ y  dec 格式化为十进制数值数据 输入和输出
  x7 D7 h; R2 \6 S# L ( |8 V, f5 N( x' L: m
  endl 输出一个换行符并刷新此流 输出
3 S6 c& O4 J8 A* X- V6 a   C  C+ B: z9 H
  ends 输出一个空字符 输出
0 p( ^$ R* m7 x7 ^ 7 i& U$ z$ V4 T0 a
  hex 格式化为十六进制数值数据 输入和输出
$ F# y7 U8 k: X* w  e8 J
" I. O; x4 L9 m8 p" W$ Y  oct 格式化为八进制数值数据 输入和输出
7 m+ l7 G% |% w/ C 5 |5 Z" F0 O' M; V
  setpxecision(int p) 设置浮点数的精度位数 输出
- z$ J  o5 V+ J; ~% A
& w0 k. a& P$ @, M; N5 ^  比如要把123当作十六进制输出:file1<
1 B9 [7 H2 Q# D6 r+ A5 p
  2、二进制文件的读写
# I9 ~. ]: ~+ x 3 e* U5 [7 \9 h; \& l# C$ r8 U
  ①put()
" C1 v+ X" M- W3 a* X& ~& r1 {
8 j# E0 ?1 U+ |  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。4 Y* C( q+ W" e4 e1 K6 }

6 ^' k3 j: ~7 r7 z" ?$ o  ②get()* i+ @2 u. `5 [3 U
: R5 {  \; e% s
  get()函数比较灵活,有3种常用的重载形式:
+ G+ {5 i- a0 b: {+ r; Z 9 L) J* O. _; [; p: E. r- P5 r+ d
  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。
( U; Q5 D, U7 y7 z% b0 x
* k* _5 B. w6 P! U% F  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。
# L4 E" T: ]# ?
; E0 Z7 L7 r4 {* A( r  |  还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。例如:- q  C% n1 a0 I7 ^2 ^

5 s4 x! S1 ]6 l  {3 }3 V  file2.get(str1,127,'A'); //从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。0 g0 C, p( i5 B" I
: X- w. b$ k3 Y1 K4 W: N1 s6 j
  ③读写数据块6 B% O5 X4 c9 _; e- `

/ |% w9 U* o9 Q/ `  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:
. c. }6 X1 S# F
$ q5 Y5 ]  P3 T3 C  read(unsigned char *buf,int num);
1 t5 x) R. g- r( O) u6 Z. L 2 _9 S' g3 c" d. E
  write(const unsigned char *buf,int num);
8 J8 g* C- e; P* J* |, K8 M& Z & J$ ?% d& x  `- {1 n( V' X
  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。
' z  x6 {2 l- T$ a$ R0 A9 U : K; `0 i& B7 {
  例:8 Q8 S" `4 w% I0 O0 r

& T5 `6 ?+ b" R* G  unsigned char str1[]="I Love You";
1 u# m6 f) _  j: F 5 p4 I& ]. H) `! q/ x
  int n[5];
8 o" T7 @1 `. U% `: I% l , o3 }$ q$ o( f0 E
  ifstream in("xxx.xxx");
( B& ~3 ~3 {9 B  T, Z, S  H
. y4 z  d7 i: F' W' ^- V$ X  ofstream out("yyy.yyy");7 _3 M9 [3 ~3 S4 z) n% R
0 X) ?! w4 Y6 ?6 G
  out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中
/ ]) o3 b  F& \" @+ u( Y: x & u- Z: k0 ?: I7 A" ?( N
  in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换, ^6 t- C6 ?9 }5 c& M

# B. P( K/ M& i3 ]0 R  in.close();out.close(); 四、检测EOF3 h3 x! M$ U5 @/ M5 [1 i1 X. i

4 W9 I0 h, I# P" {. D  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();3 O. X0 _, A) l; v" U4 }

$ r& {$ W% z3 o! e  例:  if(in.eof()) ShowMessage("已经到达文件尾!");: T( o. ^" N$ g. T3 |$ @

; U; X0 S9 Y* ~' i  五、文件定位
% O  @! [4 u% c7 V5 }
8 G9 t1 W! A* A- H/ W. g3 j# c8 h  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。它们最通用的形式如下:
' H: H7 T: A* I  t. G, d
  {- w9 ?8 o" k9 J; @  istream &seekg(streamoff offset,seek_dir origin);6 s: [- c' e) o1 I6 ]

2 p7 {4 W) D0 Q/ y7 k  ostream &seekp(streamoff offset,seek_dir origin);! S1 p, B) ]4 Q
1 I) L+ |- M% _" f
  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:0 B3 d3 R7 j% y2 o

" f. H! k# ^# G3 |4 X( v  ios::beg:  文件开头3 `% Y! S1 a  m( {  ^! x5 A2 ]
7 g& A% J6 c4 U6 D) A
  ios::cur:  文件当前位置% j* o2 c' E) T. K
+ \: B& z% R0 f, {8 Y$ z
  ios::end:  文件结尾( [' L1 p3 E5 F7 q, U
  b( e; [1 v$ c( E( d2 V) p
  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例:
0 n+ h0 ~$ ?) i: {
( a: u0 K) K- L0 T) h8 c" I- L  file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节
4 G  r" v! N3 X9 J  c. J3 E + b3 C; _& h" Y2 W
  file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节
  {9 P$ |4 ]" F# Z& K
9 a# c' L7 {7 w( M  N0 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二次开发专题模块培训报名开始啦

    我知道了