fseek与rewind到底有何区别

2024-04-12 02:08

本文主要是介绍fseek与rewind到底有何区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • c接口设置到文件头
      • 接口本身的区别
      • 运行库实现的区别
      • 结论

 

c接口设置到文件头

当我们要设置文件位置为给定流 stream 的文件的开头时,其实我们有两种选择,
直接调用rewind函数,
rewind(fp);
或者使用fseek
fseek(fp,0L,SEEK_SET);

那么这两者有什么区别呢?我们从接口本身的使用和实现两个反面来说。

接口本身的区别

首先,从接口本身来说,rewind是没有返回值的,看下边的示例代码,这段代码会有一个问题,那就是一旦rewind失败程序应该如何处理呢?

#include <stdio.h>int main ()
{int n;FILE * pFile;char buffer [27];pFile = fopen ("myfile.txt","w+");for ( n='A' ; n<='Z' ; n++)fputc ( n, pFile);rewind (pFile);fread (buffer,1,26,pFile);fclose (pFile);buffer[26]='\0';puts (buffer);return 0;
}

如果我们换成使用,fseek则代码会变成大约下边的样子,

#include <stdio.h>int main ()
{
...rewind (pFile);if(0==fseek(stream,0L,SEEK_SET)) {// todo: success} else {// todo: rewind failed!}
...
}

因此,从错误处理的角度来说,大多数情况下应该选择使用fseek.

运行库实现的区别

我们再来看看接口的实现,当然ISO C中只是定义了接口,不会对接口的实现做具体规定,因此如何实现一个接口很大程度上取决于c运行库,这有很多如BSD libc,glibc,Microsoft C run-time library 等等。。。,但是从代码设计的角度来看rewind应该要直接调用fseek比较好,或者至少两者应该是同源的,这样比较科学,也没有理由不这么做。下边我们看一下glibc的源代码里是怎么处理的,

首先看rewind,函数的定义位于文件 \glibc\libio\rewind.c中,

#include "libioP.h"
#include <stdio.h>void
rewind (FILE *fp)
{CHECK_FILE (fp, );_IO_acquire_lock (fp);_IO_rewind (fp);_IO_clearerr (fp);_IO_release_lock (fp);
}

上边代码中的_IO_rewind是一个宏,在文件libio\iolibio.h中定义,好了rewind先看到此处

#define _IO_rewind(FILE) \(void) _IO_seekoff_unlocked (FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT)

fseek的定义在文件libio\fseek.c中,

int fseek (FILE *fp, long int offset, int whence)
{int result;CHECK_FILE (fp, -1);_IO_acquire_lock (fp);result = _IO_fseek (fp, offset, whence);_IO_release_lock (fp);return result;
}

同样_IO_fseek也是一个宏,

#define _IO_rewind(FILE) \
#define _IO_fseek(__fp, __offset, __whence) \(_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) \== _IO_pos_BAD ? EOF : 0)

结论

看到这里我们已经比较了解了,在glibc中rewindfseek本质上都是调用了函数_IO_seekoff_unlocked,所以两者是同根同源的,在不考虑返回值的情况下调用哪个都可以,用rewind写起来简单些,用fseek呢,以后对于错误处理的扩展性会好一点。

https://blog.csdn.net/iceboy314159/article/details/108678895

这篇关于fseek与rewind到底有何区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/895808

相关文章

C# 委托中 Invoke/BeginInvoke/EndInvoke和DynamicInvoke 方法的区别和联系

《C#委托中Invoke/BeginInvoke/EndInvoke和DynamicInvoke方法的区别和联系》在C#中,委托(Delegate)提供了多种调用方式,包括Invoke、Begi... 目录前言一、 Invoke方法1. 定义2. 特点3. 示例代码二、 BeginInvoke 和 EndI

MySQL常见的存储引擎和区别说明

《MySQL常见的存储引擎和区别说明》MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY、Archive、CSV和Blackhole,每种引擎有其特点和适用场景,选择存储引擎时需根... 目录mysql常见的存储引擎和区别说明1. InnoDB2. MyISAM3. MEMORY4. A

在Dockerfile中copy和add的区别及说明

《在Dockerfile中copy和add的区别及说明》COPY和ADD都是Dockerfile中用于文件复制的命令,但COPY仅用于本地文件或目录的复制,不支持自动解压缩;而ADD除了复制本地文件或... 目录在dockerfile中,copy 和 add有什么区别?COPY 命令ADD 命令总结在Doc

解读Pandas和Polars的区别及说明

《解读Pandas和Polars的区别及说明》Pandas和Polars是Python中用于数据处理的两个库,Pandas适用于中小规模数据的快速原型开发和复杂数据操作,而Polars则专注于高效数据... 目录Pandas vs Polars 对比表使用场景对比Pandas 的使用场景Polars 的使用

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

java中的HashSet与 == 和 equals的区别示例解析

《java中的HashSet与==和equals的区别示例解析》HashSet是Java中基于哈希表实现的集合类,特点包括:元素唯一、无序和可包含null,本文给大家介绍java中的HashSe... 目录什么是HashSetHashSet 的主要特点是HashSet 的常用方法hasSet存储为啥是无序的

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是

Python中@classmethod和@staticmethod的区别

《Python中@classmethod和@staticmethod的区别》本文主要介绍了Python中@classmethod和@staticmethod的区别,文中通过示例代码介绍的非常详细,对大... 目录1.@classmethod2.@staticmethod3.例子1.@classmethod