当前位置:文档之家› C#IO流详解

C#IO流详解

C#IO流详解
C#IO流详解

C#IO流详解

分类:C# 2010-12-21 20:13 341人阅读评论(1) 收藏举报

文件流和数据流

不同的流可能有不同的存储介质,比如磁盘、内存等。.NET类库中定义了一个抽象类

Stream,表示对所有流的抽象,而每种具体的存储介质都可以通过Stream的派生类来实现

自己的流操作。

FileStream是对文件流的具体实现。通过它可以以字节方式对流进行读写,这种方式是

面向结构的,控制能力较强,但使用起来稍显麻烦。

此外,System.IO命名空间中提供了不同的读写器来对流中的数据进行操作,这些类通

常成对出现,一个用于读、另一个用于写。例如,TextReader和TextWriter以文本方式(即

ASCII方式)对流进行读写;而BinaryReader和BinaryWriter采用的则是二进制方式。

TextReader和TextWriter都是抽象类,它们各有两个派生类:

StreamReader、StringReader以

及StreamWriter、StringWriter。

17.3.1 抽象类Stream

Stream支持同步和异步的数据读写。它和它的派生类共同组成了.NET Framework上IO

操作的抽象视图,这使得开发人员不必去了解IO操作的细节,就能够以统一的方式处理不

同介质上的流对象。

Stream类提供的公有属性见表17.4所示。

表17.4 Stream类的公有属性

属性名类型含义

CanRead bool 是否可以读取流中的数据

CanWrite bool 是否可以修改流中的数据

CanSeek bool 是否可以在流中进行定位

CanTimeout bool 流是否支持超时机制

Length long 流的长度

Position long 流的当前位置

ReadTimeout int 读超时限制

WriteTimeout int 写超时限制

其中前4个布尔类型的属性都是只读的。也就是说,一旦建立了一个流对象之后,流的

这些特性就不能被修改了。由于流是以序列的方式对数据进行操作,因而支持长度和当前

位置的概念。在同步操作中,一个流对象只有一个当前位置,不同的程序或进程都在当前

位置进行操作;而在异步操作中,不同的程序或进程可以在不同位置上进行操作,当然这

需要文件的共享支持。最后,流的超时机制是指在指定的时间限制内没有对流进行读或写

操作,当前流对象将自动失效。

Stream类提供的公有方法则用于流的各项基本操作,请参看表17.5。表17.5 Stream类的公有方法

方法标识返回类型用途

Read(byte[], int, int) int 从流中读取一个字节序列

Write(byte[], int, int) void 向流中写入一个字节序列

ReadByte() int 从流中读取一个字节

WriteByte(byte) void 向流中写入一个字节

Seek(long, SeekOrigin) long 设置流的当前位置

SetLength(long) void 设置流的长度

Flush() void 强制清空流的所有缓冲区

(续表)

方法标识返回类型用途

Close() void 关闭流

BeginRead(byte[], int, int, AsyncCallBack) IAsyncResult 开始流对象的异步读取

EndRead(IAsyncResult) int 结束流对象的异步读取

IAsyncResult BeginWrite(byte[], int, int,

AsyncCallBack, object)

IAsyncResult 开始流对象的异步写入

EndWrite(IAsyncResult) void 结束流对象的异步写入

在不同的情况下,Stream的派生类可能只支持这些成员的部分实现。例如,网络流一

般不支持位置的概念,系统也可能禁止对缓冲区的使用。

新建一个流时,当前位置位于流的开始,即属性Position的值为0。每次对流进行读写,

都将改变流的当前位置。可以将流的当前位置理解成“光标”的概念,它类似于字处理软

件中的光标。读操作从流的当前位置开始进行,读入指定的字节数,光标就向后移动对应

的字节数。写操作也是从流的当前位置开始进行,写入指定的字节数,光标然后停留在写

完的地方。

根据需要,可以使用Position属性或Seek方法来改变流的当前位置。不过Position属性指

的都是流的绝对位置,即从流的起始位置开始计算。该值为0时表示在起始位置,等于Length

的值减1时表示在结束位置。Seek方法则需要通过SeekOrigin枚举类型来指定偏移基准,即

是从开始位置、结束位置还是当前位置进行偏移。如果指定为SeekOrigin.End,那么偏移量

就应该为负数,表示将当前位置向前移动。看下面的代码:

//打开流,当前位置为0

Stream s = File.Open("C://bootlog.txt", FileMode.Open, FileAccess.Read);

//将当前位置移动到5

s.Seek(5, SeekOrigin.Begin);

//读取1个字节后,当前位置移动到6

s.ReadByte();

//读取10个字节后,当前位置移动到16

s.Read(new byte[20], 6, 10);

//将当前位置向前移动3个单位,移动到13

s.Seek(-3, SeekOrigin.Current);

//关闭流

s.Close();

如果指定的读写操作位置超出了流的有效范围,将引发一个EndOfStreamException异常。

17.3.2 文件流FileStream

作为文件流,FileStream支持同步和异步文件读写,也能够对输入输出进行缓存以提高

性能。

FileStream类提供了多达14个构造函数,能够以多种方式来构造FileStream对象,并在

构造的同时指定文件流的多个属性。当然,其中有一些构造函数是为了兼容旧版本的程序

而保留的。对于文件的来源,可以使用文件路径名,也可以使用文件句柄来指定。以文件

路径名为例,构造FileStream对象时至少需要指定文件的名称和打开方式两个参数,其他参

数如文件的访问权限、共享设置以及使用的缓存区大小等,则是可选的;如不指定则使用

系统的默认值,如默认访问权限为FileAccess.ReadWrite,共享设置为FileShare.Read。

下面的代码以只读方式打开一个现有文件,并且在关闭文件之前禁止任何形式的共享。

如果文件不存在,将引发一个FileNotFoundException:

FileStream fs = new FileStream("c://MyFile.txt", FileMode.Open, FileAccess.Read, FileShare.None);

fs.Close();

除了使用FileStream的构造函数,也可以使用File的静态方法来获得文件流对象。File

类的静态方法Open和FileStream构造函数的参数类型基本一致,使用效果相同。例如上面的

代码等价于:

FileStream fs = File.Open("c://MyFile.txt", FileMode.Open, FileAccess.Read,

FileShare.None);

fs.Close();

File类的静态方法OpenRead和OpenWrite也能够返回一个FileStream对象,但它们只接受

文件名这一个参数。对于OpenRead方法,文件的打开方式为FileMode.Open,共享设置为

FileShare.Read,访问权限为FileAccess.Read;而对于OpenWrite 方法,打开方式为

FileMode.OpenOrCreate,共享设置为FileShare.None,访问权限为FileAccess.Write。下面两

行代码是等价的:

FileStream fs = new FileStream("c://MyFile.txt",

FileMode.OpenOrCreate,

FileAccess.Write, FileShare.None);

FileStream fs = File.OpenWrite("c://MyFile.txt");

FileStream类的ReadByte和WriteByte方法都只能用于单字节操作。要一次处理一个字节

序列,需要使用Read和Write方法,而且读写的字节序列都位于一个byte数组类型的参数中。

看下面的程序:

//程序清单P17_4.cs:using System;

using System.IO;

namespace P17_4

class FileStreamSamle

{

static void Main()

{

//创建一个文件流

FileStream fs = new FileStream("c://MyFile.txt", FileMode.Create);

//将字符串的内容放入缓冲区

string str = "Welcome to the Garden!";

byte[] buffer = new byte[str.Length];

for (int i = 0; i < str.Length; i++)

{

buffer[i] = (byte)str[i];

}

//写入文件流

fs.Write(buffer, 0, buffer.Length);

string msg = "";

//定位到流的开始位置

fs.Seek(0, SeekOrigin.Begin);

//读取流中前7个字符

for (int i = 0; i < 7; i++)

{

msg += (char)fs.ReadByte();

}

//显示读取的信息和流的长度

Console.WriteLine("读取内容为:{0}", msg); Console.WriteLine("文件长度为:{0}", fs.Length); //关闭文件流

fs.Close();

}

}

程序的输出为:

读取内容为:Welcome

文件长度为:22

最后还是要提醒一句,使用完FileStream对象后,一定不能忘记使用Close方法关闭文

件流,否则不仅会使别的程序不能访问该文件,还可能导致文件损坏。

17.3.3 流的文本读写器

StreamReader和StreamWriter主要用于以文本方式对流进行读写操作,它们以字节流为

操作对象,并支持不同的编码格式。

StreamReader和StreamWriter通常成对使用,它们的构造函数形式也一一对应。可以通

过指定文件名或指定另一个流对象来创建StreamReader和StreamWriter对象。如有必要,还

可以指定文本的字符编码、是否在文件头查找字节顺序标记,以及使用的缓存区大小。

文本的字符编码默认为UTF-8格式。在命名空间System.Text中定义的Encoding类对字符

编码进行了抽象,它的5个静态属性分别代表了5种编码格式:

? ASCII

? Default

? Unicode

? UTF-7

? UTF-8

不过,Encoding类的Default属性表示系统的编码,默认为ANSI代码页,这和

StreamReader和StreamWriter中默认的UTF-8编码是不一样的。通过StreamReader和

StreamWriter类的公有属性Encoding可以获得当前使用的字符编码。StreamReader类还有一

个布尔类型的公有属性EndOfStream,用于指示读取的位置是否已经到达流的末尾。

下面的代码从一个文件流构造了一个StreamReader对象和StreamWriter对象,还为

StreamWriter对象指定了Unicode字符编码。不过在实际应用中,为同一文件进行读写操作

所构造的两个对象通常使用同样的字符编码格式:

FileStream fs = new FileStream("c://MyFile.txt", FileMode.Create); StreamReader sr = new StreamReader(fs);

StreamWriter sw = new StreamWriter(fs,

System.Text.Encoding.Unicode);

sw.Close();

sr.Close();

fs.Close();

注意在关闭文件时,要先关闭读写器对象,再关闭文件流对象。如果对

同一个文件同

时创建了StreamReader和StreamWriter对象,则应先关闭StreamWriter对象,再关闭

StreamReader对象。否则将引发ObjectDisposedException异常。

即使是直接使用文件名来构造StreamReader或StreamWriter对象,或是使用File类的静

态方法OpenText和AppendText来创建StreamReader或StreamWriter对象,过程当中系统都会

自动生成隐含的文件流,读写器对文件的读写还是通过流对象进行的。该文件流对象可以

通过StreamReader或StreamWriter对象的BaseStream属性获得。不通过文件流而直接创建StreamReader对象时,默认的文件流对象是只读的。以同样

的方式来创建StreamWriter对象的话,默认的文件流对象是只写的。下面的程序说明了这一

点:

//程序清单P17_5.cs:

using System;

using System.IO;

namespace P17_5

{

class BaseStreamSample

{

static void Main()

{

StreamReader sr = new StreamReader("c://MyFile.txt");

Console.WriteLine("CanRead:{0}", sr.BaseStream.CanRead); Console.WriteLine("CanWrite:{0}", sr.BaseStream.CanWrite);

sr.Close();

StreamWriter sw = new StreamWriter("c://MyFile.txt");

Console.WriteLine("CanRead:{0}", sw.BaseStream.CanRead); Console.WriteLine("CanWrite:{0}", sw.BaseStream.CanWrite);

sw.Close();

}

}

}

程序P17_5.cs的输出为:

CanRead:True

CanWrite:False

CanRead:False

CanWrite:True

由于使用的是不同的流对象,此时就不能同时使用StreamReader和StreamWriter对象来

打开同一个文件。在程序P17_5.cs的代码中,如果不关闭StreamReader对象就创建

StreamWriter对象,将引发一个IOException异常。使用File类的静态方法OpenText和

AppendText时,情况也一样。

StreamReader中可以使用4种方法对流进行读操作:

? Read,该方法有两种重载形式,在不接受任何输入参数时,它读取流的下一个字符;

当在参数中指定了数组缓冲区、开始位置和偏移量时,它读入指定长度的字符数组。

? ReadBlock,从当前流中读取最大数量的字符,并将数据输出到缓冲区。

? ReadLine,从当前流中读取一行字符,即一个字符串。

? ReadToEnd,从流的当前位置开始,一直读取到流的末尾,并把所有读入的内容都

作为一个字符串返回;如果当前位置位于流的末尾,则返回空字符串。StreamReader最常用的是ReadLine方法,该方法一次读取一行字符。这里“行”的定义

是指一个字符序列,该序列要么以换行符(“/n”)结尾,要么以换行回车符(“/r/n”)

结尾。

StreamWriter则提供了Write和WriteLine方法对流进行写操作。不过这两个方法可以接

受的参数类型则丰富得多,包括char、int、string、float、double乃至object等,甚至可以对

字符串进行格式化。看下面这段代码:

//创建一个文件流

FileStream fs = new FileStream("c://MyFile.txt", FileMode.Create, FileAccess.Write);

StreamWriter sw = new StreamWriter(fs);

sw.WriteLine(25); //写入整数

sw.WriteLine(0.5f); //写入单精度浮点数

sw.WriteLine(3.1415926); //写入双精度浮点数

sw.WriteLine(’A’); //写入字符

sw.Write ("写入时间:"); //写入字符串

int hour = DateTime.Now.Hour;

int minute = DateTime.Now.Minute;

int second = DateTime.Now.Second;

//写入格式化字符串

sw.WriteLine("{0}时{1}分{2}秒", hour, minute, second);

//关闭文件

sw.Close();

fs.Close();

得到的文本文件内容是:

25

0.5

3.1415926

A

写入时间:10时11分9秒

Write和WriteLine方法的使用读者应该很熟悉,因为它们所提供的重载形式和

Console.Write以及Console.WriteLine方法完全一样。这些重载方法只是为了使用方便,实际

368 C# 2.0 程序设计教程

上写入任何类型的对象时,都调用了对象的ToString方法,然后将字符串写入流中。不同的

是,WriteLine方法在每个字符串后面加上了换行符,而Write方法则没有。

StringReader和StringWriter同样是以文本方式对流进行IO操作,但它们以字符串为操作

对象,功能相对简单,而且只支持默认的编码方式。

17.3.4 流的二进制读写器

BinaryReader和BinaryWriter以二进制方式对流进行IO操作。它们的构造函数中需要指

定一个Stream类型的参数,如有必要还可以指定字符的编码格式。和文本读写器不同的是,

BinaryReader和BinaryWriter对象不支持从文件名直接进行构造。

类似的,可以通过BinaryReader和BinaryWriter对象的BaseStream 属性来获得当前操作

的流对象。

BinaryReader类提供了多个读操作方法,用于读入不同类型的数据对象,这些方法请参

见表17.6。

表17.6 BinaryReader类的读操作方法

方法标识返回类型用途

Read(byte[],int, int) int 指定位置和偏移量,从流中读取一组字节到缓冲区

ReadBoolean() bool 从流中读取一个布尔值

ReadByte() byte 从流中读取一个字节

ReadBytes() byte[] 从流中读取一个字节数组

ReadChar() char 从流中读取一个字符

ReadChars() char[] 从流中读取一个字符数组

ReadDecimal() decimal 从流中读取一个十进制数值

ReadDouble() double 从流中读取一个双精度浮点型数值

ReadInt16() short 从流中读取一个短整型整数值

ReadInt32() int 从流中读取一个整数值

ReadInt64() long 从流中读取一个长整型整数值

ReadSByte() sbyte 从流中读取一个有符号字节

ReadSingle() float 从流中读取一个单精度浮点型数值

ReadString() string 从流中读取一个字符串

ReadUInt16() ushort 从流中读取一个无符号短整型整数值

ReadUInt32() uint 从流中读取一个无符号整数值

ReadUInt64() ulong 从流中读取一个无符号长整型整数值

使用这些方法时,注意,方法名称中指代的都是数据类型在System空间的原型。例如

读取单精度浮点型数值,方法名称是ReadSingle而不是ReadFloat,另外读取short、int、long

类型的整数值,方法名称也分别是ReadInt16、ReadInt32和ReadInt64。而BinaryWriter则只提供了一个方法Write进行写操作,但提供了多种重载形式,用于写入不同类型的数据对象。各种重载形式中的参数类型

和个数与StreamWriter中基本相同。

下面的代码演示了使用BinaryReader和BinaryWriter对象进行对应的读写操作:

//创建文件流和二进制读写器对象

FileStream fs = new FileStream("c://MyFile.bin",

FileMode.OpenOrCreate);

BinaryWriter bw = new BinaryWriter(fs);

BinaryReader br = new BinaryReader(fs);

//依次写入各类型数据

bw.Write(25);

bw.Write(0.5f);

bw.Write(3.1415926);

bw.Write(’A’);

bw.Write("写入时间:");

bw.Write(DateTime.Now.ToString());

//定位到流的开始位置

fs.Seek(0, SeekOrigin.Begin);

//依次读出各类型数据

int i = br.ReadInt32();

float f = br.ReadSingle();

double d = br.ReadDouble();

char c = br.ReadChar();

string s = br.ReadString();

DateTime dt = DateTime.Parse(br.ReadString());

//关闭文件

bw.Close();

br.Close();

fs.Close();

17.3.5 常用的其他流对象

除了FileStream类之外,代表具体流的、Stream类的常用派生类还有:

? MemoryStream,表示内存流,支持内存文件的概念,不需要使用缓冲区;

? UnmanagedM emoryStream,和MemoryStream类似,但支持从可控代码访问不可控的内存文件内容;

? NetworkStream,表示网络流,通过网络套接字发送和接收数据,支持同步和异步

访问,但不支持随机访问;

? BufferStream,表示缓存流,为另一个流对象维护一个缓冲区;

? GZipStream,表示压缩流,支持对数据流的压缩和解压缩;

? CryptoStream,表示加密流,支持对数据流的加密和解密。

同样,可以由这些流对象构造出文本读写器或二进制读写器,并进行相应方式的读写

操作。

程序P17_6.cs演示了利用文件流和缓存流来共同维护一个三角函数表:

//程序清单P17_6.cs:

using System;

using System.IO;

namespace P17_6

{

class BufferedStreamSample

{

static void Main()

{

TriangleTable table = new TriangleTable();

Console.WriteLine("请输入度数(0~179之间):");

try

{

int x = int.Parse(Console.ReadLine());

Console.WriteLine("请选择函数类型:");

Console.WriteLine("0.正弦函数1.余弦函数2.正切函数3.余切函数

");

int iType = int.Parse(Console.ReadLine());

table.Open();

double y = table.GetFunction(x, iType);

Console.WriteLine("函数值= {0}", y);

}

catch (Exception)

{

File.Delete("C://Triangle.tbl");

}

finally

{

table.Close();

}

}

}

public delegate double TwoIntFunction(int param1, int param2);

///

/// 类TriangleTable:三角函数表

///

public class TriangleTable{

private FileStream m_baseStream;

private BufferedStream m_stream;

private BinaryReader m_reader;

public TwoIntFunction GetFunction;

public TriangleTable()

{

if (!File.Exists("C://Triangle.tbl"))

{

m_baseStream = new FileStream("C://Triangle.tbl", FileMode.Create);

BinaryWriter writer = new BinaryWriter(m_baseStream);

byte[] buf = new byte[8];

for (int i = 0; i < 180; i++)

{

double sin = Math.Sin(Math.PI * i / 180);

double cos = Math.Sqrt(1 - sin * sin);

double tan = sin / cos;

double ctan = cos / sin;

writer.Write(sin);

writer.Write(cos);

writer.Write(tan);

writer.Write(ctan);

}

writer.Close();

m_baseStream.Close();

}

}

public void Open()

{

m_baseStream = new FileStream("C://Triangle.tbl",

FileMode.Open);

m_stream = new BufferedStream(m_baseStream);

m_reader = new BinaryReader(m_stream);

GetFunction = delegate(int angle, int iType)

{

if (iType < 0 || iType > 3)

throw new ArgumentOutOfRangeException("参数应为0~3之间的整数");

m_stream.Seek(sizeof(double) * (4 * angle + iType), SeekOrigin.Begin);

return m_reader.ReadDouble();

};

}

public void Close()

{

m_reader.Close();

C++输入输出流指令

补充知识1:C++中的标准输入/输出流指令 一.C++的输出 格式:cout<<表达式【<<表达式】 功能:将指定的数据流输出到屏幕 例:cout<<"Hello! \n " ; 注释1:可以输出任何类型的数据,且无须指定数据的类型 int a=5 ; float b=3.45 ; char c=’A’ ; printf ( "%d %f %c ",a,b,c) ; cout<>变量【>>变量】 功能:从键盘取得输入的数据流 例:int a; float b; scanf ( "%d %f",&a,&b) ; cin >> a>> b ; cin>>a,b ;× 可以从键盘输入: 20 31.45 各数据项间以空格分开 三.C++输入输出语句的特点 ●简洁:不需要指定数据的类型; ●需要头文件iostream.h,在程序的首行用# include命令将该文件“包含”进源程 序。

例1.4:改写例1.3(P5)的程序 # include "iostream.h" // 文件包含命令 int max(int x, int y) // 定义max( )子函数,求两个数中的较大值{ int z; if (x>y) z=x; else z=y; return z; } void main( ) { int max(int x, int y); // 此语句可省略 int a,b,c; cin>>a>>b; // 从键盘输入两个数据送到变量a和b中 c=max(a,b); // 调用max( )函数比较a和b,并把结果赋给c cout<<"max="<

C++输入输出流实验报告

深圳大学实验报告 实验课程名称:程序设计实验与课程设计 实验项目名称:实验10 C++流输入与流输出 学院:计软专业:计科 报告人:学号:班级: 3 同组人:无 指导教师:朱安民 实验时间:2014年6月16日提交时间:2014年6月16 声明: 本次实验内容由报告人和同组人独立完成,所有涉及到他人的工作均已说明。报告人和同组人均同意教师及学校为教学活动而引用本实验的内容,且无需事先征得同意和特别说明。 教务处制

一、实验目的 1.掌握标准输入输出(iostream库中标准对象cin、cout)的使用 2.掌握IO流类成员函数输入输出(cin.get, cin.getline, cin.read; cout.put, cout.write)的使用 3.掌握输出格式(标准控制符、IO流类成员函数、iomanip头文件中的控制符)控制方法 4.掌握磁盘文件的输入输出方法 二、实验说明和实验环境 1.在奥特曼类的基础上,编写一个程序,重载运算符“》”和“《”,使得用户可以直接(格式化)输出奥特曼的状态。在主程序中输入若干个(3个)奥特曼的状态,并分别将它们保存到文件RecordU.txt中。然后读取并显示文件中的内容。 2.奥特曼和怪物都具有属性:等级, 生命, 攻击, 经验, 金钱,都具有方法:初始化initial和显示状态display 在奥特曼的初始化中,需要接受外来等级参数,生命, 攻击的数值初始化为等级的10倍,金钱为等级的100倍,经验恒为0 在怪兽的初始化中,需要接受外来等级参数,生命, 攻击的数值初始化为等级的8倍,经验为等级的80倍,金钱为等级的800倍 对怪兽和奥特曼的状态输出采用运算符《重载的方法,并结合display方法使用,注意本题目要求怪兽和奥特曼的状态输出必须使用重载运算符《,不能直接使用display方法。 注意:为了实现运算符《重载,需要包含头文件 经常天降怪石会砸中奥特曼或怪兽,如果被幸运石砸中,就会处于“鸿运当头”状态,被砸对象除等级外其它属性全部翻倍;如果被厄运石砸中,就会陷入“倒霉透顶”状态,被砸对象除等级外其它属性全部减半。把“鸿运当头”封装成操作,并用重载运算符++来实现;“倒霉透顶”封装成操作,并用重载运算符--来实现。两个重载都需要用友元方法。 3.奥特曼和怪物经过一番战斗斗,需要中场休息,休息时把各自的属性值存放到一个文件中,休息结束时需要从文件中读取之前的状态继续战斗。 奥特曼和怪物都具有属性:等级, 生命, 攻击, 经验, 金钱,都具有方法:初始化initial和显示状态display 奥特曼和怪兽的属性值均来自于文件(文件的第一行是奥特曼的数据,初始状态为:等级是8,生命, 攻击的数值初始化为等级的10倍,金钱为等级的100倍,经验恒为0,文件的第二行是怪兽的数据,初始状态为等级是4,生命, 攻击的数值初始化为等级的8倍,经验为等级的80倍,金钱为等级的800倍)对怪兽和奥特曼的状态输出采用运算符《重载的方法,并结合display方法使用,注意本题目要求怪兽和奥特曼的状态输出必须使用重载运算符《,不能直接使用display方法。 把信息直接从文件读出来并赋值给奥特曼和怪兽,需要重载》运算符作为友元; 把奥特曼和怪兽的值写入文件,要求重载《运算符作为友元

CC++输入输出流总结

C/C++输入输出流总结 C++ I/O C++支持两种I/O,第一种是从C语言继承来的,一种是由C++定义的面向对象I/O系统。 1、int getchar(void);返回一个整数值,也可以指定这个值为char变量,因为这个字符包含于低位字节中(高位字节通常为0),如果有错,getchar()返回EOF。但是他有一个潜在的问题,正常情况下,getchar()缓存输入,直到键入了回车键(这个大家应该深有体会,就是getchar()貌似只认识回车键,原来是这个原因)这称为行缓冲输入,在键入的字符实际传送给程序之前必须敲入一个回车键。 2、int putchar(int c); 虽然putchar()带一个整数参数,通常可以用一个字符的变元调用它,但是只有其低位字节被实际输出到屏幕上,putchar()函数放回被写入的字符,若操作失败,返回EOF(宏EOF 被定义于stdio.h中,通常其值为-1)。 3、int getch(void); int getche(void); 两个最常用的交互式函数,对于大多数编译器,这些函数的原型都可在头文件conio.h中找到,对于某些编译器中这些函数前面有一下划线。如_getch()和_getche();这就是为什么在VS2008中经常提示要在前面加一个'_'. 4、char* gets(char* str); 读取从键盘上输入的字符串并把它存放在由其他变元所指的地址中,它从键盘读入字符,直到遇到回车键为止。回车键不输入串的一部分,相反,将空结束符放在串尾来代替,并且由gets()返回。但是使用gets()是要小心,因为它不对正在接受输入的字符数组执行边界检查。因此,用户可以键入比数组能够容纳的更多的字符。尽管对于你使用的范例程序和简单使用工具是很好的,在商用代码中一般不是用它。它的的替代物是fgets();稍后描述。5、int puts(const char* str); 将它的字符串变元写到屏幕上,后跟一新行。它的调用比printf();开销小,因为puts()只能输入字符串,不能输出数字或进行格式转换,因而puts()用的空间少且速度比printf()快。因此函数puts()经常用于代码优化,操作失败,函数puts()返回EOF,否则返回非负值。 6、int printf(const char* control_string,...);

C语言标准输入输出详解

C CC C输入输出函数 输入输出函数输入输出函数 输入输出函数 本节主要介绍Turbo C2.0标准输入输出函数和文件的输入输出函数。通过本 节的学习可以使读者掌握Turbo C2.0的屏幕输出、键盘输入输出以及磁盘文件的 读写函数, 并能开始进行一些简单的程序的编写。 控制流程语句主要包括: 条件语句、循环语句和开关语句。 1.1 标准输入输出函数 1.1.1 格式化输入输出函数 Turbo C2.0 标准库提供了两个控制台格式化输入、输出函数printf( ) 和 scanf(), 这两个函数可以在标准输入输出设备上以各种不同的格式读写数据。 printf()函数用来向标准输出设备(屏幕)写数据; scanf() 函数用来从标准输入

设备(键盘)上读数据。下面详细介绍这两个函数的用法。 一、printf()函数 printf()函数是格式化输出函数, 一般用于向标准输出设备按 规定格式输出信息。在编写程序时经常会用到此函数。printf()函数的调用格式为: printf("<格式化字符串>", <参量表>); 其中格式化字符串包括两部分内容: 一部分是正常字符, 这些 字符将按原 样输出; 另一部分是格式化规定字符, 以"%"开始, 后跟一个或几个 规定字符, 用来确定输出内容格式。 参量表是需要输出的一系列参数, 其个数必须与格式化字符串 所说明的输出 参数个数一样多, 各参数之间用","分开, 且顺序一一对应, 否则 将会出现意想 不到的错误。 1. 格式化规定符 Turbo C2.0提供的格式化规定符如下: ━━━━━━━━━━━━━━━━━━━━━━━━━━ 符号作用 ────────────────────────── %d 十进制有符号整数 %u 十进制无符号整数

C++文件的输入输出

C++中的文件输入/输出(1) 原作:Ilia Yordanov, loobian@https://www.doczj.com/doc/b113651649.html, 简介 本教程将以C++最基本的文件I/O(输出/输出)开始。此后,我将从更深入的方面,为你展示一些技巧,并分析给出一些有用的函数。 你需要对C++有一个较好的理解,否则这个教程于你而言将是陌生而毫无用处。 你的第一个程序 首先我将给出一段代码,接着再逐行进行解释。我们的第一个程序将建立一个文件,并写入一些字符: #include void main() // 程序从这里开始运行 { ofstream SaveFile(“cpp-home.txt”); SaveFile << “Hello World, from https://www.doczj.com/doc/b113651649.html, and Loobian!”; SaveFile.close(); } 仅仅如此吗?没错!这个程序将在当前运行目录下建立一个名为 cpp-home.txt的文件,并向它写入“Hello World, from https://www.doczj.com/doc/b113651649.html, and Loobian!”。 下面给出各行的含义: #include ——你需要包含此文件以使用C++的文件输入/输出函数。注意:一旦包含了这个文件,你不再需要(为了使用cout/cin)包含iostream.h,因为fstream.h已经自动包含了它。 在这个头文件中声明了若干个类,包括ifstream,ofstream及fstream,它们都继承自istream和ostream类。 ofstream SaveFile(“cpp-home.txt”); 1)ofstream即“output file stream(输出文件流)”。它将建立一个句柄(handle),以便我们以后能以一个文件流的形式写入文件。 2)SaveFile ——这是文件句柄的名字,当然,你还可以换用任何一个你想要的名称。

C++标准输入输出流

C++标准输入输出流 C++标准输入输出流 在C++语言中,数据的输入和输出(简写为I/O)包括对标准输入 设备键盘和标准输 出设备显示器、对在外存磁盘上的文件和对内存中指定的字符串存储空间(当然可 用该空间存储任何信息)进行输入输出这三个方面。对标准输入设备和标准输出设 备的输入输出简称为标准I/O,对在外存磁盘上文件的输入输出简称为文件I/O,对 内存中指定的字符串存储空间的输入输出简称为串I/O。 C++语言系统为实现数据的输入和输出定义了一个庞大的类库,它 包括的类主要有ios,istream,ostream,iostream,ifstream,ofstream,fstream,istrstream,ostrs tream,strstream等,其中ios为根基类,其余都是它的直接或间接派生类。 ios为根基类,它直接派生四个类:输入流类istream、输出流类ostream、文件流 基类fstreambase和字符串流基类strstreambase,输入文件流类同时继承了输入流

类和文件流基类(当然对于根基类是间接继承),输出文件流类ofstream同时继承了输出流类和文件流基类,输入字符串流类istrstream 同时继承了输入流类和字符串流基类,输出字符串流类ostrstream同时继承了输出流类和字符串流基类,输入输出流类iostream同时继承了输入流类和输出流类,输入输出文件流类fstream同时继承了输入输出流类和文件流基类,输入输出字符串流类strstream同时继承了输入输出流类和字符串流基类。 “流”就是“流动”,是物质从一处向另一处流动的过程。C++流是指信息从外部输入设备(如键盘和磁盘)向计算机内部(即内存)输入和从内存向外部输出设备(如显示器和磁盘)输出的过程,这种输入输出过程被形象地比喻为“流”。为了实现信息的内外流动,C++系统定义了I/O 类库,其中的每一个类都称作相应的流或流类,用以完成某一方面的功能。根据一个流类定义的对象也时常被称为流。如根据文件流类fstream 定义的一个对象fio,可称作为fio流或fio文件流,用它可以同磁盘上一个文件相联系,实现对该文件的输入和输出,fio就等同于与之相联系的文件。 C++系统中的I/O类库,其所有类被包含在iostream.h,fstream.h和strstrea.h这三个系统头文件中,各头文件包含的类如下: iostream.h包含有:ios, iostream, istream, ostream, iostream_withassign, istream_withassign, ostream_withassign等。 fstream.h包含有:fstream, ifstream, ofstream和fstreambase,以及iostream.h

C++的输入和输出与标准输出流

* 掌握:输入输出的含意;文件流以及输入/输出的格式控制;标准输出在C++程序中的应用。 * 理解:C++类库中的常用流类。 * 了解:C++的I/O对C的发展。 重点、难点 ◆输入输出的含意;文件流以及输入/输出的格式控制;标准输出在C++程序中的应用。 一、C++ 输入输出的含义 以前所用到的输入和输出,都是以终端为对象的,即从键盘输入数据,运行结果输出到显示器屏幕上。从操作系统的角度看,每一个与主机相连的输入输出设备都被看作一个文件。程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。C++的输入与输出包括以下3方面的内容: 1、对系统指定的标准设备的输入和输出。简称标准I/O。(设备) 2、以外存磁盘(或光盘)文件为对象进行输入和输出。简称文件I/0。(文件) 3、对内存中指定的空间进行输入和输出。简称串I/O。(内存) C++采取不同的方法来实现以上3种输人输出。为了实现数据的有效流动,C++系统提供了庞大的I/O类库,调用不同的类去实现不同的功能。 二、C++的I/O对C的发展—类型安全和可扩展性 C语言中I/O存在问题: 1、在C语言中,用prinff和scanf进行输入输出,往往不能保证所输入输出的数据是可靠的、安全的。学过C语言的读者可以分析下面的用法:想用格式符%d输出一个整数,但不小心错用了它输出单精度变量和字符串,会出现什么情况?假定所用的系统int型占两个字节。printf("%d",i);//i为整型变量,正确,输出i的值 printf("%d",f);//f为单精度变量,输出变量中前两个字节的内容 printf("%d","C++");//输出字符串"C++”的起始地址 编译系统认为以上语句都是合法的,而不对数据类型的合法性进行检查,显然所得到的结果不是人们所期望的。 2、在用scanf输入时,有时出现的问题是很隐蔽的。如

c++输入输出流实验报告

实验四输入输出流 实验课程名:面向对象程序设计(C++) 专业班级:学号:姓名: 实验时间:实验地点:指导教师: 一、实验目的和要求 (1) 理解类和对象的概念,掌握声明类和定义对象的方法。 (2) 掌握构造函数和析构函数的实现方法。 (3) 初步掌握使用类和对象编制C++程序。 (4) 掌握对象数组、对象指针和string类的使用方法。 (5) 掌握使用对象、对象指针和对象引用作为函数参数的方法。 (6) 掌握类对象作为成员的使用方法。 (7) 掌握静态数据成员和静态成员函数的使用方法。 (8) 理解友元的概念和掌握友元的使用方法。 二、实验内容 1.定义描述职工工资的类Laborage,数据成员为职工号(No)、姓名(Name[8])、应发工资(Ssalary)、社保金(Security)、实发工资(Fsalary)。定义公有成员函数Input(),在Input()函数内输入职工号、姓名、应发工资、社保金,实发工资由公式:Fsalary=Ssalary-Security计算。定义输出职工工资的成员函数Show()。在显示函数Show()中,职工号、姓名的输出域宽为8、左对齐,其余数据的输出域宽为10、右对齐、保留小数点后两位,输出格式均用预定义格式控制函数设置。在主函数中用Laborage类定义职工对象数组a[3]。用Input()输入职工工资,用Show()显示每个职工的工资。(提示:用getline输入姓名后,必须用回车结束姓名输入) 实验数据: 1001 Zhou Zhi 3000 200 1002 Chen Hua 4000 400 1003 Wang Fan 5000 500 实验代码: #include #include #include using namespace std; class Laborage { public: Laborage(){} void input();

相关主题
文本预览
相关文档 最新文档