热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

让你提前认识软件开发学长的软件开发经验总结(12)

让你提前认识软件开发---学长的软件开发经验总结(12)配置文件读取及文件操作 【文章摘要】       在通信领域的软件开发项目中,C语言是主流的编程语言,而文件操作在其

第1部分 重新认识C语言

配置文件读取及文件操作

 

【文章摘要】

        在通信领域的软件开发项目中,C语言是主流的编程语言,而文件操作在其中又占有很重要的地位。此外,为了体现产品的灵活性,可添加配置文件对某些重要的参数进行按需配置。这就要求程序能够准确读取到各个配置项的值。

       本文以一个实际的小软件为例,介绍了C语言中配置文件的读取方法和重要的文件操作函数的使用方法,为相关软件开发项目提供了有益的参考。

【关键词】

        C语言 文件函数 
配置文件 操作

 

1.前言

        在一般的软件项目中,常常需要用C语言对文件进行操作。在诸如对账之类的程序中,尤其如此。而C语言中有关文件操作的函数多达数十种,熟悉常用函数(fopenfclosefgetsfreadfwrite)的操作可以提高项目的编程效率,具有很现实的意义。

        灵活性是优秀软件吸引用户的特性之一,为了体现软件的灵活性,可以将相关参数放置到一个配置文件中,用户可以根据需要进行设置。因此,C语言中的配置文件读取函数也值得关注。

        本文以作者编写过的软件为例,对C语言中配置文件的读取和常用的文件操作函数的使用方法进行了详细的介绍。

 

2.本文使用的软件、文件操作函数和配置文件介绍

2.1本文使用的软件

        本文使用的软件基于MFC实现,有一个用户操作的界面,如图1所示。

bubuko.com,布布扣

1软件操作界面

        在本软件中,三个主要按钮实现的功能为:

        (1)“添加到输出框”按钮:从配置文件中读取相关信息,并输出到上面的空白框中(空白框的属性为LIST BOX)

        (2)“保存到文件”按钮:将从配置文件中读取到的信息保存到指定命名格式的文件中。

        (3)“上传到FTP”按钮:将(2)中生成的文件上传到指定的FTP目录中。

 

2.2本文中使用的文件操作函数

        本文使用的文件操作函数包括fopenfwritefflushfclose等,对它们的详细说明如下:

        (1) fopen函数

        作用:打开文件

        表头文件:#include

        定义函数:FILE *fopen(const char *path, const char *mode);

        函数说明:参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。

        mode有下列几种形态字符串:

        r:打开只读文件,该文件必须存在。

        r+:打开可读写的文件,该文件必须存在。

        w:打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。

        w+:打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

        a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。

        a+:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。

        上述的形态字符串都可以再加一个b字符,如rbw+bab+等组合,加入b字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,包含Linux都会忽略该字符。由fopen()所建立的新文件会具有
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)
权限,此文件权限也会参考umask值。

        返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败,则返回NULL,并把错误代码存在errno中。

        附加说明:一般而言,打开文件后会作一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。

        (2) fwrite函数

        作用:将数据写至文件流

        表头文件:#include

        定义函数:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

        函数说明:fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr指向欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。fwrite()会返回实际写入的nmemb数目。

        返回值:返回实际写入的nmemb数目。

         (3) fflush函数

        作用:更新缓冲区

        表头文件:#include

        定义函数:int fflush(FILE *stream);

        函数说明:fflush()会强迫将缓冲区内的数据写回参数stream指定的文件中。如果参数streamNULLfflush()会将所有打开的文件数据更新。

        返回值:成功返回0,失败返回EOF,错误代码存于errno中。

        错误代码:EBADF参数stream指定的文件未被打开,或打开状态为只读。

         (4) fclose函数

        作用:关闭文件

        表头文件:#include

        定义函数:int fclose(FILE *stream);

        函数说明:fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。

        返回值:若关闭文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno中。

        错误代码:EBADF表示参数stream非已打开的文件。

 

2.3本文中使用的配置文件

        为了程序的正常运行,一般都会事先约定配置文件的命名及格式。在本文中,配置文件为Config.ini(ini为配置文件的常用后缀),文件中涉及到的配置项及注释如下:

;用于配置文件的本地存放路径

[General]

;文件的本地存放路径

LocalPath  = D:\

;文件前缀

FilePrefix = EmployeeInfo

;文件后缀(形如txt,注意,不要加.)

FileSuffix = txt

 

;添加信息条数和具体信息(姓名+工号)

[EmployeeInfo]

;消息条数

MsgCount = 3

;消息内容

content1 = 00000001张三

content2 = 00000002李四

content3 = 00000003王五

 

; FTP信息,需按照实际情况来配置

[FTP]

; IP地址

IPAddr   =

;用户名

UserName =

;密码

Password =

;传输方式:2 - BIN1 - ASC

Mode = 1

;远端路径: FTP上传时存放文件的路径

FTPPath =

 

       在配置文件中,将相关联的项放置在同一个大项中,用[]括起来(如上面的红色字体所示),各个小项的值直接放到等号的后面,注释部分用分号开头。

 

2.4本文中使用的读取配置操作函数

         本文中使用的读取配置操作函数为GetPrivateProfileIntGetPrivateProfileString,对它们的详细说明如下:

         (1) GetPrivateProfileInt函数

        作用:从配置文件中读取一个值,并将结果转换为整型数据后保存到变量中。

        原型:UINT GetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName);

        各参数的意义:

         1) lpAppName:配置文件中的大项,用[]括起来的部分(2.3节的红色字体所示)

         2) lpKeyName:各大项下小项的字段名称,如2.3节中General下的LocalPath

         3) nDefault:如果配置文件中没有这个配置项,那么代码中取的默认值。

         4) lpFileName:配置文件名,如本文中的Config.ini

         举例:如本程序要获取MsgCount的值,则代码如下:

            int  iMsgCount = 0;

            iMsgCount = GetPrivateProfileInt("EmployeeInfo", "MsgCount", 0, “Config.ini”);

         (2) GetPrivateProfileString函数

         作用:从配置文件中读取一个值,并将结果转换为字符串型数据后保存到变量中。

         原型:DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName);

         各参数的意义:

         1) lpAppName:配置文件中的大项,用[]括起来的部分(2.3节的红色字体所示)

         2) lpKeyName:各大项下小项的字段名称,如2.3节中General下的LocalPath

         3) lpDefault:如果配置文件中没有这个配置项,那么代码中取的默认值。

         4) lpReturnedString:代码中存放读取值的字符数组。

         5) nSize:一般为lpReturnedString字符数组的大小。

         6) lpFileName:配置文件名,如本文中的Config.ini

        举例:如本程序要获取FilePrefix的值,则代码如下:

        char szFilePrefix[100] = {0};

       GetPrivateProfileString("General", "FilePrefix",   "EmployeeInfo", szFilePrefix, 100, strINIFILE);

 

2.5本文中使用的FTP操作函数

         本文中使用的FTP操作函数为GetFtpConnectionPutFile,对它们的详细说明如下:

         (1) GetFtpConnection函数

        作用:连接FTP服务器。

        原型:CFtpConnection* GetFtpConnection(LPCTSTR pstrServer, LPCTSTR pstrUserName, LPCTSTR pstrPassword, INTERNET_PORT nPort, BOOL bPassive);

        各参数的意义:

        1) pstrServer:服务名,即FTP服务器的IP地址。

        2) pstrUserName:用户名,即登录FTP服务器的用户名。

        3) pstrPassword:密码,即登录FTP服务器的密码。

        4) nPort:端口号,该参数默认值为INTERNET_INVALID_PORT_NUMBER

        5) bPassive:该项的默认值为FALSE

        (2) PutFile函数

        作用:FTP上传文件。

        原型:BOOL PutFile(LPCTSTR pstrLocalFile, LPCTSTR pstrRemoteFile, DWORD dwFlags, DWORD_PTR dwContext);

        各参数的意义:

         1) pstrLocalFile:带存放路径的本地文件名。

         2) pstrRemoteFile:带存放路径的远端文件名,即文件存放在FTP服务器的何处。

         3) dwFlags:标识,该项取默认值FTP_TRANSFER_TYPE_BINARY

         4) dwContext:上下文标识,该项取默认值1

 

3.程序流程

        如2.1节所述,本程序主要实现三个功能,对应的配置文件如2.3节所示。每个功能的流程及相关说明如下:

3.1将配置文件中的数据添加到输出框

        (1)该功能的流程图

       如图2所示:

bubuko.com,布布扣

2将配置文件中的数据添加到输出框流程图

(2)消息内容格式及异常考虑

        本程序采用的消息内容格式为:工号姓名,如“00000001张三”,“00000001”表示工号,“张三”为姓名。在输出框里面,也是这样显示的。

        本流程的异常情况主要考虑以下方面:

        1) MsgCount项的值为空或0

        2)消息内容项(content1content2content3)为空或出现内容完全相同。

        3)消息内容格式不正确,即不是“工号姓名”的格式。

        4)工号相同(一般而言,员工工号不能相同)

 

3.2将配置文件中的数据写入文件

        (1)该功能的流程图

        如图3所示:

bubuko.com,布布扣

3将配置文件中的数据写入文件流程图

         (2)文件命名、文件消息内容格式及异常考虑

         文件命名格式为:FilePrefix时分秒.FileSuffix,如“EmployeeInfo155431.txt”。

         文件消息内容格式与输出框格式一样,即“工号姓名”。

         本流程考虑的异常情况与3.1节相同。

         (3)有关文件操作函数的使用说明

         1)对于fopen函数,由于要向文件中写入数据,因此“mode”参数可以采用“a”等,但不能采用“r”等表示只能读取的参数。

         2)使用fwrite函数将数据写入文件,注意要在每条数据的最后面加上“\n”表示回车换行。

         3)在写入数据完成之后,一定要加上fclose函数关闭文件,并且fclose函数一定要与fopen函数配对,且在使用fclose函数之后,要将文件指针置为null

 

3.3将生成的文件上传到FTP服务器

        (1)该功能的流程图

       如图4所示:

bubuko.com,布布扣

4将生成的文件上传到FTP服务器流程图

        (2)有关FTP操作的说明

        1)在执行操作之前,一定要确保FTP服务器的各项参数都配置正确。对于“Mode”项,1表示以ASC方式上传,2表示以二进制方式上传。

        2) FTP操作的最大重试次数可根据需要进行设置,一般为3次。

 

4.对本软件进行测试

        在程序运行起来之后,接下来的工作就是对之进行大量的测试,一定要对本程序涉及到的三个主要功能均进行充分的测试。

        为了使得测试顺利进行,在运行本软件之前,需要将本软件和配置文件放在同一个文件夹的同一级目录下。当然,也可以在代码中设定特殊的配置文件存放目录。

        对于“将配置文件中的数据添加到输出框”功能,检查输出框上面显示的内容是否和配置文件里面的信息一致,并对几种异常情况进行大量的测试。

        对于“将配置文件中的数据写入文件”功能,检查文件命名是否符合要求、文件存放地址是否正确、文件里面的内容是否和输出框显示的信息一致,同时要对几种异常情况进行大量的测试。

        对于“将生成的文件上传到FTP服务器”功能,检查FTP服务器上对应目录是否有文件存在,并对异常情况(FTP信息配置不准确、本地文件不存在、远端路径不存在等)进行一定的测试。

 

5.总结

        文件操作和配置文件在实际的软件开发项目中是很常见的,掌握C语言中常用文件操作函数的使用方法是对一个软件开发工程师的基本要求。

        本文用实例来描述了C语言中常用的文件操作函数的用法及配置文件的使用方法。“冰冻三尺,非一日之寒”,要想熟练掌握C语言中常用文件操作函数及配置文件的用法,还需要我们不断地练习和总结。

 

 

(欢迎访问南邮BBS:http://bbs.njupt.edu.cn/)
(欢迎访问重邮BBS:http://bbs.cqupt.edu.cn/nForum/index)

(本系列文章每周更新两篇,敬请期待!本人新浪微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)

让你提前认识软件开发---学长的软件开发经验总结(12),布布扣,bubuko.com


推荐阅读
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
author-avatar
手机用户2602887787
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有