如何正确用C语言读取文件

在C语言中可以将相关定义的数据按照内存的原样写入文件,这对于大规模数据来说比较方便,因为文件的尺寸比单纯的ASCII存储要小很多。

下面简单说明自己在存储如下定义的结点数据的体会。以二进制存储文件时,只存储uid(人名), pwd(密码), org(组织),

modifyDate(修改日期)中的六个变量。程序本身是有一个循环双链表,不存储指针数据。按照人名uid降序存入文件,并建立首字符的索引。

#define LENGTH_PWD 32

#define LENGTH_UID 24

#define LENGTH_ORG 8

typedef struct Date

{

int year,month,day;

int hour,minute,second;

}DATE;

typedef struct People

{

char uid[LENGTH_UID];

char pwd[LENGTH_PWD];

char org[LENGTH_ORG];

DATE modifyDate;

struct People *next,*prior;

}PEOPLE;

在使用ftell获取每行记录首个位置后存入索引文件。由于数据文件按字母顺序排列的,所以只要知道不同字符的起点,之后再返回定位数据文件,这样不必从开始处查找另外当之后的数据过了匹配的关键字的时候可以直接返回。杂乱顺序的数据,查找会从开始一直查找到末尾。而排序好的,只有最坏情况才会扫描整个数据文件。建立索引并排序,可以大大减少查找的次数提高查询的效率。

经过仔细调试发现,当写入以下面的方式,首次读取前面字符串均正确,但是之后的就错位了,通过UltraEdit的十六进制观看。整数实际存取与其位数有关。其中visit为PEOPLE类型的指针指向数据结点。

fwrite(visit->uid,sizeof(char),LENGTH_UID,fpDat);

fwrite(visit->pwd,sizeof(char),LENGTH_PWD,fpDat);

fwrite(visit->org,sizeof(char),LENGTH_ORG,fpDat);

fprintf(fpDat,"%d%d%d %d%d%d",

visit->modifyDate.year,visit->modifyDate.month,visit->modifyDate.day,

visit->modifyDate.hour,visit->modifyDate.minute,visit->modifyDate.second);

发现使用fprintf会把整数输出为字符串形式到文件中去,也就是说数字123,是按字符1、2、3分别存放的。但是使用fwrite(&visit->modifyDate.year,1,sizeof(int),fpDat),发现这个时候是按照整数在内存中存放字节存储的。通过改变这样的方法后是可以正常存储的。

使用固定长度来存储文件的好处是,在使用工具查看时可以有类似表格的效果比较整齐。当你需要压缩文件长度的时候,比如字符串只要有一个断点就可以了,不必要加很多的\0。你可以使用fprintf与fscanf但是结果却发现,使用%s输入的时候不会把结尾标志给加进去,当你使用逗号等分隔,发现在读取的时候还是会把逗号放在一个字符串中。因此当使用fprintf方法输出字符串的时候,最好在后面再加上fputc(‘\0’,fpDat)。

当然我使用了比这偷懒的方法,使用

存放:fprintf(fpDat,”%s\t%s\t%s\t%d-%d-%d

%d:%d:%d”,……)

读取:fscanf(fpDat, ”%s\t%s\t%s\t%d-%d-%d

%d:%d:%d”,……)

这样使用是没有问题的,可以正常读取或输入。

当然建议大家还是运用比较匹配的方法,如果不是考虑文件的体积,我觉得用fread与fwrite比较好一些也比较稳定一些。

文件的存取尽量用比较配对的方法,在使用fprintf的时候二进制存储的优势就被削弱了。从最终的数据观察,可以不难理解fprintf与fscanf主要针对文本格式的文件存取,fwrite与fread是针对二进制格式文件的存取。固定长度的存入每记录单元的大小是固定的。另外,将来也可以做到知道要读多少行,可以直接通过计算来跳到指定的行数来读取。不像文本格式一样,组成的内容会有些变动,字符串也是有长短之分的。

下面对使用较多的fseek函数做一下自己的一些体会。

当你需要随机访问文件的时候,你知道需要访问磁盘文件一连串的位置。如何优化磁盘访问的性能呢。我们知道最坏的情况是读取文件一会从头部一会又从尾部开始。我们尽可能让磁头可以按一定增量单向移动,那么需要事先对读取文件位置列表进行简单排序。那么我们要知道访问文件后,进行一下列读取操作后,文件流的位置也已经发生改变。这个时候,我们需要运用一定的技巧。

定位的位置假设为beginPos,要访问的下一个位置假定为nextPos,那么等读取完毕后又到了一个新的位置假定为currentPos,那么实际上我们要从当前位置再移动一个位移。很容易通过数学公式算出应该为nextPos-currentPos。fseek的函数的参数有很细微的变化。

fseek(fp,posToMove ,SEEK_SET/SEEK_END/SEEK_CUR);

选用什么方式移动与当前的位置有很大关系,主要看移动的大小。一般情况下使用SEEK_SET进行首次定位,以后只要按增量顺序即可使用SEEK_CUR作为方式。

SEEK_SET表示从文件头根据第二个参数移动;

SEEK_END表示从文件尾根据第二个参数移动;

SEEK_CUR表示从当前位置根据第二个参数移动;

我们需要大量的实践与测试,才能体会怎样用函数,以及什么时候使用,另外如何避免一些可能存在的问题。

通过简单的实践,明白了许多道理,当然在这之中还是可以发现很多的乐趣。做一件事情需要不断地反复思考,要仔细考虑如何去优化,如何去提高效率。只有进行不断地思考,才能取得长足的进步。

c语言如何读文件,如何正确用C语言读取文件相关推荐

  1. java读文件几种方式_java中读取文件的方式有哪几种

    java中读取文件的方式有哪几种 发布时间:2020-06-19 13:36:48 来源:亿速云 阅读:135 作者:鸽子 读取文件有多种方式,基于传统的输入流方式或基于nio的Buffer缓冲对象和 ...

  2. 文件------概念、基本操作、打开文件的方式、按行读取文件内容、复制文件、文件/目录的常用管理操作、文本文件的编码格式、练习1-4

    文件的概念 文件的概念 计算机的文件,就是存储在某种长期储存设备上的一段数据 长期存储设备包括:硬盘.U盘.移动硬盘.光盘... 文件的作用 将数据长期保存下来,在需要的时候使用 文件的存储方式 在计 ...

  3. c语言中读和写的作用,c语言文件读写

    c语言文件读写 从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种. ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码.ASCII码 ...

  4. c语言lua读文件,file-io – 在Lua中逐行读取文件

    Lua使用相同的底层C实现模型管理文件(此模型也被其他编程语言使用,这是相当常见的).如果您不熟悉这种查看文件的方式,那么术语可能不清楚. 在该模型中,文件表示为具有所谓的当前位置的字节流.当前位置是 ...

  5. c语言读文件时 fgetc,[求助]用fgetc()读取文件时遇到的问题~~

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 文件input.txt Today is sunday. Our beautiful pools had turned brownish          ...

  6. c++语言循环读写文件夹,在C++中逐行读取文件

    file.txt的内容包括: 5 3 6 4 7 1 10 5 11 6 12 3 12 4 其中,5 3是一个坐标对.如何在C++中逐行处理此数据? 我可以得到第一行,但如何得到文件的下一行? if ...

  7. python读取文件_python这么受欢迎,你知道如何以正确的方式来读取文件内容吗

    前言 对于互联网的开发人员来说,读取写入文件几乎是代码中常见的一种操作.但是经常性的打开关闭文件,浪费资源不说,当文件大的时候读取的效率也不高.所以今天我们一起看一个便捷的模块linecache.li ...

  8. c语言中的目标程序的正确含义,C语言程序设计练习题整理要点.doc

    第1章 C语言初步 一.选择题: C 语言是在( )语言的基础上产生的. A. A B. B C. D D. E 在 C 语言中,每个语句必须以( )结束. A. 回车符 B. 冒号 C. 逗号 D. ...

  9. php读取文件行读,如何在php中按行读取文件

    您可以使用fgets()函数逐行读取文件: $handle = fopen("inputfile.txt", "r"); if ($handle) { whil ...

  10. java 到服务器上读文件路径,java访问linux服务器读取文件路径

    java访问linux服务器读取文件路径 内容精选 换一换 通过ADC从Host获取文件.参见准备环境完成环境配置.以运行用户登录安装Toolkit组件的服务器.执行命令,从Host获取B.java, ...

最新文章

  1. [翻译] NSRegexTester
  2. 白话Elasticsearch50-深入聚合数据分析之基于doc values正排索引的聚合内部原理
  3. Python字典数据类型及基本操作
  4. MVC路由中routes.IgnoreRoute({resource}.axd/{*pathInfo}) 到底什么意思!
  5. Deepgreen数据库日志清理脚本
  6. 【英语学习】【WOTD】cumulate 释义/词源/示例
  7. android cydia使用教程,Android Hook工具Cydia Substrate使用
  8. c#开源消息队列中间件EQueue 教程
  9. fastReport 小总结
  10. 深度学习基础(十)—— 稀疏编码(二)
  11. 多个pdf合并成一个pdf_多个PDF怎么合并?这些PDF合并方法很简单!
  12. 6.2.6 String_Number
  13. 车辆信息管理系统(C语言大作业)
  14. 中兴云桌面服务器,中兴云桌面解决方案.pdf
  15. Windows蓝屏漏洞(利用多种途径与分析)
  16. 微信小程序源代码_下厨房菜谱APP
  17. 发布工程到私有仓库maven
  18. no matching provisioning profile found
  19. [Image_Codec]常见图片格式的封装及编解码-Android平台(三)JPG
  20. OpenGL ES的状态机说法其实也没那么云山雾照,比较容易理解!

热门文章

  1. jdk 7 官方下载
  2. 正规矩阵 酉矩阵 对角矩阵
  3. 华电C语言题库(循环中等难度)
  4. 博科光纤交换机配置及管理 B/S篇
  5. bmp转换为YUV420p指南
  6. syslog (cactiez)
  7. Unity激光雷达仿真调研(svl)
  8. 网络工程师和网络运维工程师的区别
  9. 宽带上行下行测试软件,上行网速(电信300m宽带上行下行)
  10. 无人驾驶虚拟仿真(十五)--障碍物检测与识别1