c语言fputc,c语言fseek函数

3358 blog.csdn.net/libing 403/article/details/73158972

讨论三个问题: fseek 函数和ftell )函数的工作方式、二进制流的使用方式以及如何使程序可移植。

fseek 和ftell )的结构

头文件: #include

函数定义: int

seekfile*stream,long offset,int whence );

函数说明: fseek ) )用于移动文件流的读取/写入位置。

1 .参数stream是打开的文件指针。

2 .参数offset

是偏移量。 此参数表示从起始点移动的距离。 干参数必须是长类型的值。 正前进)、负后退)或0 ) )。

3 .参数whence

模式。 这个参数决定起点。 根据ANSI标准,stdio.h头文件中规定了几个表示模式的明确的标量例如

常数)。 如下表所示:

表1文件的起始点模式

模式

偏移的起点

SEEK_SET

文件开头

SEEK_CUT

文件的当前位置

SEEK_END

文件末尾

在的实现中可能缺少这些定义,并且这3种模式可以分别由数值0L、1L、2L表示。 l表示该值为长类型。

fseek ) )函数的一些调用示例。 fp是文件指针。

seekFP,0L,SEEK_SET ); //转到文件开头

seekFP,10L,SEEK_SET ); //移动到文件的第10个字节

seekFP,2L,SEEK_CUR ); //从文件的当前位置前进2个字节

seekFP,0L,SEEK_END ); //移动到文件末尾

fseekFP,-10,SEEK_END ); //从文件末尾后退10个字节

1

2

3

4

5

这些调用有一些限制。 稍后再解释。 如果一切正常,则fseek函数的返回值为0; 如果发生错误,例如,如果尝试移动到文件范围之外,返回值将为-1。

ftell ) )

函数用于获取文件读/写指针的当前位置。 其原型是长文件file * stream );

【参数】stream是打开的文件指针。

【返回值】成功时返回当前的读写位置,失败时返回-1。

对于二进制文件,返回从文件开头到文件末尾的字节数。

对于文本文件,返回的值可能没有实际意义,但可用于存储当前读写位置以供fseek )函数使用

随机访问文件时,文件的位置会频繁地前后移动,因此程序不容易确定文件的当前位置。 您可以使用fseek函数,然后调用函数ftell )来快速确定文件的当前位置。 ftell ) )

fseek ) )一起经常使用。

在第一个unix实现中,ftell )通过返回从文件开头开始的字节数来确定文件的位置。 的第一个字节到文件开头的距离为0。 美国航空

C规定,此定义适用于以二进制模式打开的文件,而对于以文本文件打开的文件则不同。

请看以下过程的示例。

#包含

#包含

#define CNTL_Z ‘\032 ‘

#define SLEN 81

入主void ) )。

{

char file[SLEN];

char ch;

FILE *fp

长计数,最后;

企业文件处理: puts );

Scanfs ),文件;

if ) FP=fopenfile,’ rb ‘ ) ) ==NULL ) ) ) ) ) ) ) ) ) )。

{

reverse can ‘ topen % s\n ‘,file );

exitexit_failure;

}

seekFP,0L,SEEK_END );

last=ftellFP;

forcount=1L; count=last; count )

{

seekFP,-count,SEEK_END );

ch=getcFP;

ifch!=CNTL_Z ch!=’\r ‘ )

Putcharch );

}

putcharn ) );

floseFP );

re

turn 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

下面是该程序对一个文件的输出:

Enter the name of the file to be processed:

Cluv[用户输入]

.C ni naht ylevol erom margorp a

ees reven llahs I taht kniht I

1

2

3

4

5

6

注意,运行程序前先在可执行程序的目录下准备一个叫Cluv的文件,里面存有以下内容,才可能得到上面的输出笔者是在windows下Cygwin模拟的Linux环境下运行)。名为Cluv的文件:

I think that I shall never see

a program more lovely than in C.

1

2

3

该程序使用二进制模式,以便处理MS-DOS文本和UNIX文本。但是,是在使用其他格式的文本文件的环境可能无法正常工作。

首先,分析下面的语句:

​ fseekfp,

0L, SEEK_END);

把当前位置设置为距文件末尾0字节偏移量。也就是说,该语句把当前位置设置在文件结尾。下一条语句:

last=ftellfp);

把文件开始到文件结尾的字节数赋值给last。

然后是一个for循环:

for count = 1L; count <= last; count++)

{

fseekfp, -count, SEEK_END);

ch = getcfp);

if ch != CNTL_Z && ch != ‘\r’)

putcharch);

}

1

2

3

4

5

6

7

第一轮迭代,把程序定位到文件结尾的第一个字符即文件的最后一个字符)。然后,长须打印该字符。然后,程序打印该字符。下一轮迭代把程序定位到前一个字符,并打印该字符。重复这一过程直到文件的第一个字符,并打印。

二进制模式和文本模式

上面的示例程序在UNIX和MS-DOS环境下都可以运行。UNIX只有一种文件格式,所以不需要进行特殊的转换。但是MS-DOS要格外注意,许多MS-DOS编辑器都用Ctrl+Z标记文本文件的结尾。以文本模式打开这样的文件时,C能识别这个作为文件结尾标记的字符。但是,以二进制模式打开文件时,Ctrl+Z字符被看做文件中的一个字符,而实际的文件结尾符在该字符的后面。文件结尾符可能紧跟Ctrl+Z字符后面,或者文件中可能用空字符填充,使该文件的大小是256的倍数。在DOS环境下不会打印空字符,上面程序就包含了贩子打印Ctrl+Z字符的代码。

二进制模式和文本模式的另一个不同之处是:MS-DOS用\r\n组合表示文本文件换行。以文本模式打开相同的文件时,C程序把\r\n“看成”是\n。但是,以二进制模式打开该文件时,程序能看见这两个字符。因此,上面的程序还包含了不打印\r的代码。通常UNIX文本文件既没有Ctrl+Z,也没有\r,所以这部分代码不会影响大部分UNIX文本文件。

ftell函数在文本模式和二进制模式中的工作方式不同。许多系统的文本文件格式与UNIX的模型有很大的不同,导致从文件开始处统计的字节数称为一个毫无意义的值。ANSI

C规定,对与文本模式,ftell)返回值可以作为fseek)的第2个参数。对于MS-DOS,ftell)返回值把\r\n当做一个字符计数。

可移植性

理论上,fseek)和ftell)应该符合UNIX模型,但是,不同系统存在着差异,有时确实无法做到与UNIX模型一致。因此,ANSI

对这些函数降低了要求。下面是一些限制

在二进制中,实现不必支持SEEK_END模式。因此无法保证上面的程序的可移植性。移植性更高的方法是逐字节读取整个文件直到文件末尾。C预处理器的条件编译指令提供了一种系统方法处理这种情况。

在文本模式中,只有以下调用能保证其相应的行为。

函数调用

效果

fseekfile, 0L, SEEK_SET)

定位至文件开始处

fseekfile, 0L, SEEK_CUR)

保持当前位置不动

fseekfile, 0L, SEEK_END)

定位至文件结尾

fseekfile,ftell-pos, SEEK_SET)

到距文件开始处ftell-pos的位置,ftell-pos是ftell)的返回值

快三稳赚10大技巧END);

把当前位置设置为距文件末尾0字节偏移量。也就是说,该语句把当前位置设置在文件结尾。下一条语句:

last=ftellfp);

把文件开始到文件结尾的字节数赋值给last。

然后是一个for循环:

for count = 1L; count <= last; count++)

{

fseekfp, -count, SEEK_END);

ch = getcfp);

if ch != CNTL_Z && ch != ‘\r’)

putcharch);

}

1

2

3

4

5

6

7

第一轮迭代,把程序定位到文件结尾的第一个字符即文件的最后一个字符)。然后,长须打印该字符。然后,程序打印该字符。下一轮迭代把程序定位到前一个字符,并打印该字符。重复这一过程直到文件的第一个字符,并打印。

二进制模式和文本模式

上面的示例程序在UNIX和MS-DOS环境下都可以运行。UNIX只有一种文件格式,所以不需要进行特殊的转换。但是MS-DOS要格外注意,许多MS-DOS编辑器都用Ctrl+Z标记文本文件的结尾。以文本模式打开这样的文件时,C能识别这个作为文件结尾标记的字符。但是,以二进制模式打开文件时,Ctrl+Z字符被看做文件中的一个字符,而实际的文件结尾符在该字符的后面。文件结尾符可能紧跟Ctrl+Z字符后面,或者文件中可能用空字符填充,使该文件的大小是256的倍数。在DOS环境下不会打印空字符,上面程序就包含了贩子打印Ctrl+Z字符的代码。

二进制模式和文本模式的另一个不同之处是:MS-DOS用\r\n组合表示文本文件换行。以文本模式打开相同的文件时,C程序把\r\n“看成”是\n。但是,以二进制模式打开该文件时,程序能看见这两个字符。因此,上面的程序还包含了不打印\r的代码。通常UNIX文本文件既没有Ctrl+Z,也没有\r,所以这部分代码不会影响大部分UNIX文本文件。

ftell函数在文本模式和二进制模式中的工作方式不同。许多系统的文本文件格式与UNIX的模型有很大的不同,导致从文件开始处统计的字节数称为一个毫无意义的值。ANSI

C规定,对与文本模式,ftell)返回值可以作为fseek)的第2个参数。对于MS-DOS,ftell)返回值把\r\n当做一个字符计数。

可移植性

理论上,fseek)和ftell)应该符合UNIX模型,但是,不同系统存在着差异,有时确实无法做到与UNIX模型一致。因此,ANSI

对这些函数降低了要求。下面是一些限制

在二进制中,实现不必支持SEEK_END模式。因此无法保证上面的程序的可移植性。移植性更高的方法是逐字节读取整个文件直到文件末尾。C预处理器的条件编译指令提供了一种系统方法处理这种情况。

在文本模式中,只有以下调用能保证其相应的行为。

函数调用

效果

fseekfile, 0L, SEEK_SET)

定位至文件开始处

fseekfile, 0L, SEEK_CUR)

保持当前位置不动

fseekfile, 0L, SEEK_END)

定位至文件结尾

fseekfile,ftell-pos, SEEK_SET)

到距文件开始处ftell-pos的位置,ftell-pos是ftell)的返回值

Published by

风君子

独自遨游何稽首 揭天掀地慰生平