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

写文件与错误处理

写文件与错误处理一、背景上一篇总结探究了who的实现过程。学会了使用联机帮助来为自己披荆斩棘、解决问题。who命令从utmp结构中读出数据并且通过标准输出方式输出。而并未往文件中写数据。这一篇总结将会

写文件与错误处理

一、背景

上一篇总结探究了who的实现过程。学会了使用联机帮助来为自己披荆斩棘、解决问题。who命令从utmp结构中读出数据并且通过标准输出方式输出。而并未往文件中写数据。这一篇总结将会讨论之。另外将讨论linux系统调用的错误处理方式。

二、写文件

1.查找写文件的系统调用

写文件的系统调用当然可以直接从书中查找到是write。但运用联机帮助的知识也很容易的查找到。首先要联想到写文件相关联的一定是读文件系统调用readread现在已经熟悉了。那么在SEE ALSO中就可以看到写文件为write

接下来当然是用帮助文档查看下write的使用方法。

头文件与使用方法皆在其中。

2.编写cp命令

cp命令是复制粘贴命令,它会在你指定的位置创建一个新的文件并将你指定的旧文件的内容写入到新文件中。明白原理后就应该知道这里需要这几个系统调用:打开旧文件、创建新文件、读旧文件到缓冲区、写缓冲区的数据至新文件、将两个文件都关闭。这里除了创建新文件现在还不知道使用哪个系统调用外,其它的系统调用都已经使用过了。

不过这里用联机帮助我也没在SEE ALSO中找得到新建文件的系统调用。在书上查找到使用creat并使用联机帮助查询其头文件与使用方法。

在这里我发现它的使用方法与open的使用方法极为相似。而且SYNOPSIS(概览)都是一样的。只怪自己大意,其实在open中就应该想到creat是创建新的文件系统调用了。

cp命令的实现代码如下:

#include

#include

#include

#include

 

#define LEN 10000

#define MODE 0644

 

void error(char *,char *);

 

int main(int argc,char *argv[])

{

        int in_fd,out_fd,number;

        char buffer[LEN];

        if(argc!=3)

         { fprintf(stderr,"usage like this: %s source destination.\n",argv[0]);

        exit(1);

        }

        if((in_fd=open(argv[1],O_RDONLY))==-1)

          error("Cannot open the sourcefile.\n",argv[1]);

        if((out_fd=creat(argv[2],MODE))==-1)

          error("Cannot open the destinationfile.\n",argv[2]);

        while((number=read(in_fd,buffer,LEN))>0)

          if(write(out_fd,buffer,number)!=number)

          error("failed to write to the destination.\n",argv[2]);

        if(number==-1)

        error("failed to read from the sourcefile.\n",argv[1]);

        if((close(in_fd)==-1) || (close(out_fd))==-1)

        error("failed to close the file","");

        return 0;

}

 

void error(char *a,char *b)

{

        fprintf(stderr,"error:%s",a);

        perror(b);

exit(1);

}

 

这个程序的实现其实相对于who会简单一点。主要是需要处理好错误处理。错误处理后面会分析到。

 

二、处理系统调用中的错误

1.错误的出现

系统调用中可能会出现许多种类型的错误,比如open:当打开一个文件你却没权限时会报错,如果已经打开很多文件内存不足也会报错,如果你打开的这个文件根本就不存在,当然也会报错。总之错误方式多多。而无论是opencreat还是readwriteclose,报错都是会返回一个值:-1的。

2.确定错误种类

种类繁多的错误,都只是返回-1,可若要进行某种修正,那么编程者知道到底是何种错误就显得尤其重要了。确定错误种类的命令errno,查看其联机帮助可以看到各种错误代码的说明,多得数不胜数。我随便截了一部分。

也就是说,当errno==(某个错误代码)时,就应该是某种错误类型,在标准输出就应该输出其对应的说明了。程序示例如下:

#include

extern int errno;

int sample()

{

        int fd;

        fd=open("file",O_RDONLY);

        if(fd==-1)

        {

        printf("Cannot open file:");

        if(errno==ENOENT)

        printf("There is no such file.\n");

        if(errno==EINTR)

        printf("Interrupted while opening file.\n");

        if(errno==EACCESS)

        printf("You do not have permission to open file.\n");

        ...

这段程序是不完整的程序,就是为了说明每一种错误类型均对应某一种应标准输出的错误说明。

3.perror

这个命令是一种更为方便省心的错误处理方式。之前我的程序代码中就多次出现了。将前面的sample程序修改一下:            

    int sample()

{

        int fd;

        fd=open("file",O_RDONLY);

        if(fd==-1)

        {

        perror("cannot open this file");

        exit(1);

        ...

由此可以看出这种错误输出方式确实简单方便的多。所以非常常用。

这里看一个实例,刚才编写的cp命令来错误的使用:

我用自己编写的cp来复制1233.c,可以看到其报错信息如前所述。

 

三、总结

    写文件沿袭了上一次的总结,只是新学习了两个系统调用:creatwrite。而处理调用中的错误就是学会使用perror命令。errno运作方式了解即可。



推荐阅读
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
author-avatar
qixian0392_648
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有