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

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

admin 楼主

2014-1-23 14:57:18

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

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

x
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;
& ]( z! u) E  L) T3 W* ^$ K0 f8 w( Z& ^
: O/ H: M8 u. j+ L- Z2 q1 k  在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:: a& e9 y* I8 W: U

9 J  s6 Z; O8 G6 G  1、插入器(<<)/ T  Z7 }% {0 C9 Z
9 G! l/ B2 Z4 K( D( m# h
  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。" M* b7 B2 r& v5 A$ q

( G4 a0 e$ r/ ~! E5 \  2、析取器(>>), {2 U) o- J* J

. n: F+ Q6 L. p1 V) o  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。$ l% y2 S6 j1 h- f; _" I; p3 V
2 E& S' Z0 s& L( W" `6 ?
  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
. s# d1 ]  z, o & X* e' o0 d' d+ i2 H$ y/ V
  一、打开文件
5 R6 k$ ]+ L$ c: H
3 h: }9 M8 T- O3 ^3 `  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:1 G& P  u9 d0 I

1 n1 w& Z. F6 e  K6 Q$ P3 i  void open(const char* filename,int mode,int access);参数:/ u/ {4 H6 R, R; R1 w% j
) P5 r8 x4 F5 V  X* p
  filename:  要打开的文件名
, g4 _0 k9 R  Y$ J& _8 E& s
  N( ~! }7 x  G3 O1 _  mode:    要打开文件的方式9 ~0 v" [! c2 V8 X+ x

3 u/ V7 x: v9 j  e0 E+ V5 L  access:   打开文件的属性
3 R8 n8 u6 K4 z/ X : L1 u% H2 H6 S3 q
  打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
, ^4 B9 P$ I8 O1 d! Q2 e ' @2 v; ]( F* R4 S) @& H- Z4 R
  ios::app:   以追加的方式打开文件
) L6 G9 r; A: g! @3 A
5 a" \& s3 _& j8 q1 V- ~  o  ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
0 \6 t9 E% w6 E  X
: ]6 R' V6 v$ T- c" o7 |  ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文# K2 A  G; u. X" O
% r5 b1 P4 o$ g$ d5 p- \/ H- Q! L
  ios::in:    文件以输入方式打开(文件数据输入到内存)
4 G) C. r; A& T0 G 9 Z: a" z8 i4 W8 `' t8 n# G5 _/ \' H0 \
  ios::out:   文件以输出方式打开(内存数据输出到文件)8 v, r$ A: R# x6 b
' Q% ^* h" R' H+ C6 ^
  ios::nocreate: 不建立文件,所以文件不存在时打开失败
: T+ |* b1 @) {) W& a( J6 ~ ! i3 Y* T# O7 V" v0 W* H
  ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败4 [3 V9 b: Q6 d" Z  O6 Q2 Z) a

' Z2 {2 ^$ ~4 o  ios::trunc:  如果文件存在,把文件长度设为0
1 Y( x  Z; K, A; [ / Z  k; [! F1 g# H
  可以用“或”把以上属性连接起来,如ios::out|ios::binary; `8 R4 x/ R# k

* \0 G( N6 }& [- |! j- Y, h  打开文件的属性取值是:! a. N( {6 d' [, F" t

7 x3 P0 Q% A& W: r, x  0:普通文件,打开访问
" Q# i6 q2 v, ?% n   I* @* v4 {- L) D+ n
  1:只读文件
8 Z5 P8 D3 b+ R 6 `+ \& R: k/ ~
  2:隐含文件1 x9 D* _; X! d) T% f9 R8 W7 O
; O$ q) K4 }) d  x
  4:系统文件! [! D- K- x  \' D1 G( {
4 B7 \1 i- \# R2 I
  可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。/ L' S; ~/ z4 h& P  Y

) |9 [) y$ v# _" @$ t  例如:以二进制输入方式打开文件c:\config.sys
  b1 v: J$ g4 Q& N3 w
5 z/ M* n6 p5 n% @  fstream file1;$ R) n; N# `/ [
6 |' C& L" q# B0 Y
  file1.open("c:\\config.sys",ios::binary|ios::in,0);
* ~" {, y8 I" Z; w % }% O4 V" L1 v' s- ?7 m* N2 M
  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
- Y" w2 C  {9 X7 h 9 j: d5 k* M5 @9 ~
  file1.open("c:\\config.sys"); <=> file1.open("c:\\config.sys",ios::in|ios::out,0);! C8 v5 Y1 M# d# J4 Z
# ]0 n/ ^% `3 _
  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:
, y, _" f9 t4 N- @
% Y6 ?1 c5 y) G% y  fstream file1("c:\\config.sys");  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。; w& `6 ?& j5 q- ?

$ R/ W+ r; t8 n/ L5 i7 B8 J, S  ifstream file2("c:\\pdos.def");//以输入方式打开文件" i% N; t( o: d8 A8 [. n- E) v! c
9 p/ _* y. l7 D' c2 v3 O! {& g
  ofstream file3("c:\\x.123");//以输出方式打开文件  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
% y, ]# q9 u3 O 4 h1 ?+ d$ A5 }  P6 H/ M
  二、关闭文件# k8 L. d' ~& w2 _0 p1 s
' M+ u! J: J; F+ a' Q& O2 s' Z' i
  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。  D& C" U2 d1 d0 r7 x
6 g: E: g) j6 N6 l$ @1 B: `
  三、读写文件1 g" v5 R7 g2 w1 _& B4 V
# C8 O( I& f. i8 X$ w6 ~" C0 P
  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式
% s# ~* ^* i3 r0 v
. @1 n) ~$ r) L$ y  1、文本文件的读写
- x! h+ D8 k3 p( E* b$ W" F
9 ^) i8 S) e% C5 v; W  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:
2 |; ^! z  W! a9 r) v 5 \3 I  z- P# X& ^- _/ o
  file2<<"I Love You";//向文件写入字符串"I Love You". u$ o/ K& `+ @& Y

% @5 @; |5 w& |. W  int i;, L( r+ Q  J; l: i+ s2 w' F6 X8 g
: x, H0 ?* W% o/ n
  file1>>i;//从文件输入一个整数值。" b5 t6 Q9 \* ~

& F2 [' c& C* g: |  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些
- c7 m3 J: X3 ?- w5 o
6 j- M" I' |! t! |5 q  操纵符 功能 输入/输出0 ?) E4 o+ m( }' p# J$ _
4 [, g* K/ j4 u  D) x8 I
  dec 格式化为十进制数值数据 输入和输出0 j. {  \* e0 w: O5 J: K! O- k

% |' Z# o& ]+ ]. |8 t  endl 输出一个换行符并刷新此流 输出
. v* V: U0 [7 B3 z 5 ]% ^) Z/ o! I4 Z3 A8 @
  ends 输出一个空字符 输出
) u4 r, i! I% o. I: \8 F' v" Z8 J % K# ^  I2 a1 W; _$ w" f- R- `& }
  hex 格式化为十六进制数值数据 输入和输出# K4 y0 `4 [' v6 y. K
7 ?6 i( P. w% }: E+ ?3 ^! @. R& J8 ^
  oct 格式化为八进制数值数据 输入和输出
$ _* r4 Y6 M- R3 {5 F2 w5 z1 c" z & D5 w5 G9 p" j. i8 t) M/ c* \' y
  setpxecision(int p) 设置浮点数的精度位数 输出
* a9 @4 P$ _1 ]9 h
: Z; W$ s7 T) M6 N$ M  比如要把123当作十六进制输出:file1<

' ^7 }( [. @$ w" \  2、二进制文件的读写
5 i5 l$ g2 ?$ Q2 u ; V9 A% ]1 H/ u& ~, K
  ①put()
7 E+ M; I/ t8 S& z 6 j; J6 Z3 ^! w! H
  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。
* o2 S! U$ J7 b; r  \& s- Y, T( G + _  K. y. ]/ E+ A2 @5 _2 @
  ②get()" Y8 H* l! }8 w- _+ a- Y

0 k6 [7 i- X% b  P) K  get()函数比较灵活,有3种常用的重载形式:
% E/ m# e% p7 l# e' u$ s9 \. }: r+ k( Q
, U# g+ A/ j& i8 x! X$ O  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。
1 k7 c: u8 ^5 ^/ m8 r6 B3 M
" w9 ~/ j" [) O3 u+ u2 s  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。
* Y% n& ^) W& |# F7 r1 ~7 y 9 Q% k- U+ r! ^! ?+ l+ f7 r6 O! R) @
  还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。例如:3 h& K* L: _: O1 L9 C2 O, w' e

! V& N9 P; \: q0 k9 W# ?# x  Z$ E. k  file2.get(str1,127,'A'); //从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。+ F3 t2 s5 u  o& h% z& `% h
% Y& n/ E/ b+ C  d; R, N
  ③读写数据块
! b; N. k* H8 c, q
1 `0 e% T/ `; F1 G% O  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:
7 X0 S+ b$ g4 Q) c* A0 r 1 O$ O* O8 V! T3 ^
  read(unsigned char *buf,int num);! w: e6 O  H9 K9 p$ C
1 k; f4 m( V% m
  write(const unsigned char *buf,int num);
# H6 M0 u4 W' i* T4 H
' Z7 m5 u/ G1 B" b' `  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。: D2 J- f% d; V# \6 J) ?/ E
& T; m: ^$ z; k2 E3 H( E
  例:
- J3 ]' Q4 F& k; H# F2 k) }; C# A + [, U/ t" Y! q8 F& w
  unsigned char str1[]="I Love You";
) H* O7 }6 W) i. a0 _; ~7 \) ~- w
' r# C* r  S. T% ~* j% `  T5 a  int n[5];
/ t/ M- C" ?3 T
: d2 y& u. z2 E, O  ifstream in("xxx.xxx");
. ^4 a& I7 R* K* W$ r. ?* Y ; g* k; {5 v7 j7 t- J/ Z
  ofstream out("yyy.yyy");0 r, B  F" K0 t* y! ^

+ D/ e: g& S' s7 ]+ ?" U6 a! r  out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中! n, c. s& \% F4 d$ V& O; M

0 J+ _% w- E$ a2 N) N4 P, q  m  in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换# D, {- D! k* L
4 p9 C' w8 }  V% I" U
  in.close();out.close(); 四、检测EOF
! O+ h6 r1 g$ V- d3 L
# k6 o; i# a* [( @  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();3 G8 B1 @4 t; t5 X- u$ G# \
" K( {" b" E" L7 o( N
  例:  if(in.eof()) ShowMessage("已经到达文件尾!");5 h; d/ Y2 [' _% z. P4 W

6 g) s8 ~% U0 C3 q% V  五、文件定位
% B+ m. x4 p1 I2 @ , `5 U6 P3 i2 o" [5 L" Q
  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。它们最通用的形式如下:4 T! A8 k# u; \6 d, P' K" P6 I# Q
( c& w  p) n: _9 `
  istream &seekg(streamoff offset,seek_dir origin);
5 H& L1 N8 K& m+ J  `; u3 H: N
$ n& Q* {8 n# e  ostream &seekp(streamoff offset,seek_dir origin);3 s5 M7 ~! `* A5 |
" V+ U) a7 g3 t) X2 ^# C; }: M7 F
  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
% R; B' o- P+ A# h8 f3 @( v* W6 E ) B4 Y5 K$ D  s/ r* R+ l! n" t
  ios::beg:  文件开头) i  s& a' N! \0 ~  ^4 h$ r' V+ k5 M; l
  S6 \6 H. ]# P3 D$ {
  ios::cur:  文件当前位置- \/ a$ X9 p; B2 ~& `
6 n% s9 \3 ~0 p! N1 O* m+ I! Z
  ios::end:  文件结尾
- q! K$ [2 \1 y  ^5 L5 @* W6 e+ v
0 i. q$ l% @/ ^3 h/ y. A  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例:3 M/ I7 l5 d+ p: ?( b; ~7 i

- X0 {# Z, V* m  file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节
" A7 N9 Y7 E, ~  F1 T( z2 `% E
' J9 i: A# p. ~  ?) u  file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节

. z; r: C% o: q
5 j- V( L3 A) R0 {1 ]: Z
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了