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

Unix系统编程()open,read,write和lseek的综合练习

需求:程序的第一个命令行参数为将要打开的文件名称,余下的参数则指定了文件上执行的输入输出操作。每个表示操作的参数都以一个字母开头,紧跟以相关值(中间无空格分隔)。soffet:从文件开始检索

需求:程序的第一个命令行参数为将要打开的文件名称,余下的参数则指定了文件上执行的输入输出操作。每个表示操作的参数都以一个字母开头,紧跟以相关值(中间无空格分隔)。

 

soffet:从文件开始检索到offset字节位置

rlength:在文件当前偏移量处,从文件中读取length字节数据,并以文本形式显式

Rlength:在当前文件偏移量处,从文件中读取length字节数据,并以十六进制形式显式

wstr:在当前文件偏移量处,由文件写入由str指定的字符串

 

#include 
#include 
#include 
#include "get_num.h"
#include 
#include 
#include <string.h>
int main(int argc, char *argv[]) {
        size_t  len;
        off_t offset;
        int fd, ap, j;
        char *buf;
        ssize_t numRead, numWritten;

  /* usage */
        if(argc <3 || strcmp(argv[1], "--help") == 0)
                printf("%s file {r | R | w | s} ...\n",
                                                 argv[0]);

        /* open or create file */
        fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
                                                S_IROTH | S_IWOTH);

        /* is system call success */
        if(fd == -1)
                printf("open file error\n");

        /* biz code */
        for(ap = 2; ap ) {
                switch(argv[ap][0]) {
                case 'r':                   /* Display bytes at current offset, as text */
                case 'R':                   /* Display bytes at current offset, in hex */
                        len = getLong(&argv[ap][1], GN_ANY_BASE, argv[ap]);

                /* alloc buffer */
                buf = malloc(len);

                /* is alloc success */
                if(buf == NULL)
                        printf("malloc error\n");

                numRead = read(fd, buf, len);
                if(numRead == -1)
                        /* read fail */
                        printf("read\n");

                /* end of file */
                if(numRead == 0)
                        printf("%s: end-of-file\n", argv[ap]);
                else {
                        printf("%s: ", argv[ap]);
                        for(j=0; j)
                                if(argv[ap][0] == 'r')
                                        printf("%c", isprint((unsigned char) buf[j]) ? buf[j] : '?');
                                else
                                        printf("%O2x ", (unsigned int) buf[j]);
                        printf("\n");
                }

                /* free memory */
                free(buf);
                break;
                case 'w':                   /* Write string at current offset */
                        numWritten = write(fd, &argv[ap][1], strlen(&argv[ap][1]));
                        if(numWritten == -1)
                                printf("write error\n");
                        printf("%s: wrote %ld bytes\n", argv[ap], (long) numWritten);
                        break;
                case 's':
                        offset = getLong(&argv[ap][1], GN_ANY_BASE, argv[ap]);
                        if(lseek(fd, offset, SEEK_SET) == -1)
                                printf("lseek error!\n");
                        printf("%s: seek successed\n", argv[ap]);
                        break;
                default:
                        printf("Argument must start with [rRws]: %s\n", argv[ap]);
                }
        }

        exit(0);
}

 

get_num.h

 

#ifndef GET_NUM_H
#define GET_NUM_H

#define GN_NONNEG          01   /* Value must be >= 0 */
#define GN_GT_0            02   /* Value must be > 0 */

                                /* By default, integers are decimal */
#define GN_ANY_BASE      0100   /* Can use any base - like strtol(3) */
#define GN_BASE_8        0200   /* Value is expressed in octal */
#define GN_BASE_16       0400   /* Value is expressed in hexadecimal */

long getLong(const char *arg, int flags, const char *name);

int getInt(const char *arg, int flags, const char *name);

#endif

get_num.c

#include 
#include 
#include <string.h>
#include 
#include 
#include "get_num.h"

static void gnFail(const char *fname, const char *msg, const char *arg,
                   const char *name) {
  fprintf(stderr, "%s error", fname);

  if (name != NULL)
    fprintf(stderr, " (in %s)", name);

  fprintf(stderr, ": %s\n", name);

  if(arg != NULL && *arg != '\0')
    fprintf(stderr, "        offending text: %s\n", arg);

  exit(EXIT_FAILURE);
}

static long getNum(const char *fname, const char *arg, int flags,
                   const char *name)
{
  long res;
  char *endptr;
  int base;

  if(arg == NULL || *arg == '\0')
    gnFail(fname, "null or empty string", arg, name);

  base = (flags & GN_ANY_BASE) ? 0 : (flags & GN_BASE_8) ? 8 :
    (flags & GN_BASE_16) ? 16 : 10;

  errno = 0;

  res = strtol(arg, &endptr, base);

  if(errno != 0)
    gnFail(fname, "strtol() failed", arg, name);

  if(*endptr != '\0')
    gnFail(fname, "nonnumeric characters", arg, name);

  if((flags & GN_NONNEG) && res <0)
    gnFail(fname, "negative value not allowed", arg, name);

  if((flags & GN_GT_0) && res <= 0)
    gnFail(fname, "value must be > 0", arg, name);

  return res;
}

long getLong(const char *arg, int flags, const char *name)
{
  return getNum("getLong", arg, flags, name);
}

int getInt(const char *arg, int flags, const char *name)
{
  long res;

  res = getNum("getInt", arg, flags, name);
  if(res > INT_MAX || res < INT_MIN)
    gnFail("getInt", "integer out of range", arg, name);

  return (int) res;
}

推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
author-avatar
SU大肥婆_545
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有