15.8 十六进制倾印码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> int main(int argc, char **argv)
{
//输入流
FILE *source;
//左侧行号区域
int line = 0;
//读入的个数
size_t readCount;
//循环计数
int idx;
//一个字节的16进制字符串
char hex[4];
//16进制显示区域,32个16进制加上3个空白
char hexArea[36] = {'\0'};
//字符显示区域
char alphaArea[17];
//存放读取数据
char buffer[17]; if(argc > 1){
//argv第二个是参数
source = fopen(*(argv + 1), "rb");
}else{
//如果没有文件名,标准输入当做输入源
source = stdin;
} //source流检查
if(source == NULL){
printf("[%s] %d\n", *(argv + 1) , argc);
perror("\n");
exit(EXIT_FAILURE);
} //循环直到文件结束
while(!feof(source)){
//读取16个字节,如果没有读取剩下的字节
readCount = fread(buffer, sizeof(char), 16, source);
for(idx = 0; idx < readCount; idx++){
//转换成大写16进制
sprintf(hex, "%02X", buffer[idx]); //四个字节一个空格
if(idx > 0 && (idx % 4) == 3){
strcat(hex, " ");
strcat(hexArea, hex);
}else{
strcat(hexArea, hex);
} if(isprint(buffer[idx])){
alphaArea[idx] = buffer[idx];
}else{
alphaArea[idx] = '.';
}
}
alphaArea[readCount] = '\0'; printf("%06x %-36s*%-16s*\n", line * 16, hexArea, alphaArea);
line++;
hexArea[0] = '\0';
alphaArea[0] = '\0';
} return 0;
}

/home/mao/test文件内容:

运行:

15.9 fgrep实现

#include <stdio.h>
#include <string.h>
#include <stdlib.h> #define MAX_BUF 510 int main(int argc, char ** argv)
{
FILE *file;
char buff[MAX_BUF];
char search[MAX_BUF];
char currentFile[MAX_BUF];
int lineNumber; //目标字符串
strcpy(search, *(argv + 1));
if(argc > 2){
//文件打开
argv += 2;
while(*(argv) != NULL){
strcpy(currentFile, *argv);
file = fopen(currentFile, "r");
if(file == NULL){
perror(currentFile);
exit(EXIT_FAILURE);
}
lineNumber = 1;
while(fgets(buff, MAX_BUF, file) != NULL){
//读取文件以后,进行比对,如果找到打印信息,如果没有,继续读
if(strstr(buff, search) != NULL){
printf("%-10s:%-5d %s\n", currentFile, lineNumber, buff);
}
lineNumber++;
}
//下一个文件
argv++;
}
}else{
//标准输入打开
while(fgets(buff, MAX_BUF, stdin) != NULL){
if(strstr(buff, search) != NULL){
printf("%s %s\n", search, buff);
}else{
printf("no found %s in %s\n", search, buff);
}
}
}
return 0;
}

目录下三个文件1.txt 2.txt 3.txt,运行:

15.10 校验checkSum

#include <stdio.h>
#include <string.h>
#include <stdlib.h> #define MAX_BUF 100 int main(int argc, char ** argv)
{
FILE *file;
FILE *cksFile;
char cksFileName[MAX_BUF];
char currentFile[MAX_BUF];
int ch;
int isToFile = 0;
unsigned short int checkNum;
if(argc > 1){
//文件输入,检查是否 -f
if(strcmp(*(argv + 1), "-f") == 0){
isToFile = 1;
//检查-f是否合法
if(argc == 2){
printf("-f illegal when reading standard input");
exit(EXIT_FAILURE);
}
//指向-f后的文件名
argv += 2;
}else{
argv += 1;
} //开始校验文件
while(*argv != NULL){
//保存当前文件名
strcpy(currentFile, *argv);
if(isToFile){
//生成并打开cks文件流
strcpy(cksFileName, currentFile);
strcat(cksFileName, ".cks");
cksFile = fopen(cksFileName, "w");
if(cksFile == NULL){
perror("");
exit(EXIT_FAILURE);
}
}
//打开需要读入的文件
file = fopen(currentFile, "r");
if(file == NULL){
perror("");
exit(EXIT_FAILURE);
}
//开始计算checkSum
checkNum = 0;
while((ch = fgetc(file)) != EOF){
checkNum += ch;
}
//输出checkSum
if(isToFile){
fprintf(cksFile, "%5s checkSum: %hu", currentFile, checkNum);
fclose(cksFile);
}else{
printf("%5s checkSum: %hu", currentFile, checkNum);
} //关闭文件流,并准备打开下一个文件
fclose(file);
argv++;
}
}else{
//处理标准输入
checkNum = 0;
while((ch = getchar()) != EOF){
checkNum += ch;
}
printf("%u\n", checkNum);
} return 0;
}

运行:

15.11 商品存货记录

#include <stdio.h>
#include <string.h>
#include <stdlib.h> #define MAX_DES_BUF 40
#define MAX_BUF 20
#define SUCCESS 1
#define FAILED 0 //单件商品信息结构体
typedef struct {
//商品描述
char description[MAX_DES_BUF];
//商品数量
unsigned int quantity;
//商品价格
float price;
//商品总价值
float totalPrice;
//已售利润
float profit;
//是否已删除标示
short int isDeleted;
//行号
unsigned int lineNum;
} GoodsMsg; //添加记录成功返回 SUCCESS 失败FAILED
int newRecord(char *order, FILE *file);
//购买
int buyRecord(char *order, FILE *file);
//出售
int sellRecord(char *order, FILE *file);
//删除
int delRecord(char *order, FILE *file);
//打印
int printPartRecord(char *order, FILE *file);
//打印所有
void printRecord(FILE *file);
//计算总价值
float totalPrice(FILE *file); int main(int argc, char **argv)
{
FILE *file;
char FileName[MAX_DES_BUF];
char order[MAX_DES_BUF]; //没有指定文件名,生成记录文件
if(argc == 1){
strcpy(FileName, "D:\\GoodsRecord.txt");
}else{
strcpy(FileName, *(argv + 1));
} //打开文件流,如果文件不存在,则重新生成文件
file = fopen(FileName, "rb+");
if(file == NULL){
//新建文件
file = fopen(FileName, "wb+");
if(file == NULL){
perror("");
exit(EXIT_FAILURE);
}else{
printf("Create File %s", FileName);
}
}else{
printf("open file %s", FileName);
} printf("$:");
//读取命令
while(fgets(order, 40, stdin) != NULL){
//匹配命令
if(strncmp(order, "end", 3) == 0){
//结束
printf("bye bye\n");
break;
}else if(strncmp(order, "new", 3) == 0){
//添加记录
if(newRecord(order, file) == SUCCESS){
printf("\nnew success: %s\n", order);
}
}else if(strncmp(order, "buy", 3) == 0) {
if(buyRecord(order, file) == SUCCESS){
printf("buy: %s\n", order);
}
}else if(strncmp(order, "sell", 4) == 0) {
if(sellRecord(order, file) == SUCCESS){
printf("sell: %s\n", order);
}
}else if(strncmp(order, "delete", 6) == 0) {
if(delRecord(order, file) == SUCCESS){
printf("del: %s\n", order);
}
}else if(strncmp(order, "print all", 9) == 0) {
printRecord(file);
}else if(strncmp(order, "print", 5) == 0) {
printPartRecord(order, file);
}else if(strncmp(order, "total", 5) == 0) {
printf("total: %f\n", totalPrice(file));
}else{
printf("unknow order\n");
} printf("$:");
} fclose(file); return 0;
} //添加记录成功返回 SUCCESS 失败FAILED
int newRecord(char *order, FILE *file)
{
//需要写入文件商品信息结构体
GoodsMsg *good = (GoodsMsg *)malloc(sizeof(GoodsMsg));
//文件读取的临时结构体
GoodsMsg *temp = (GoodsMsg *)malloc(sizeof(GoodsMsg));
//行号
unsigned int lineNum = 1;
//商品价格
float price = 0;
//商品数量
unsigned int quantity;
//商品描述
char descript[MAX_BUF] = {'\0'}; //重置流的位置从头开始读取
rewind(file); //将命令行格式化输入参数中
if(sscanf(order, "new %s , %u , %f\n", descript, &quantity, &price) == 3){
//初始化数据;
strcpy(good -> description, descript);
good -> quantity = quantity;
good -> price = price;
good -> totalPrice = price * quantity;
good -> profit = 0;
good -> isDeleted = 0; //寻找插入位置,写在已删除商品位置,还是文件末尾添加
while(fread(temp, sizeof(GoodsMsg), 1, file)){
//查找已删除产品
if(temp -> isDeleted == 1){
//定位到该条信息前,准备覆盖信息
fseek(file, -sizeof(GoodsMsg), SEEK_CUR);
break;
}else{
//wb+模式中,读之后如果需要写,则需定位到当前位置
fseek(file, 0L, SEEK_CUR);
}
lineNum++;
}
//添加行号
good -> lineNum = lineNum;
//写入商品信息
fwrite(good, sizeof(GoodsMsg), 1, file);
//写入缓冲并释放资源
fflush(file);
free(temp);
free(good); return SUCCESS;
} return FAILED;
} //购买
int buyRecord(char *order, FILE *file)
{
//读取的商品结构体
GoodsMsg *good = (GoodsMsg *)malloc(sizeof(GoodsMsg));
unsigned int partNumber;
unsigned int quantity;
float price; rewind(file);
//命令符合格式
if(sscanf(order, "buy %u , %u , %f\n", &partNumber, &quantity, &price) == 3) {
//查看数据更新位置
while (fread(good, sizeof(GoodsMsg), 1, file)) {
//查找产品位置
if (good->lineNum == partNumber) {
//定位到该条信息前
fseek(file, -sizeof(GoodsMsg), SEEK_CUR);
//重新计算均价和商品总价值
good -> totalPrice = (good -> totalPrice) + quantity * price;
good -> quantity = (good -> quantity) + quantity;
good -> price = (good -> totalPrice) / good -> quantity;
//更新商品信息
fwrite(good, sizeof(GoodsMsg), 1, file);
fflush(file);
return SUCCESS;
}
}
//其他情况都返回FAILED
}
return FAILED;
} //出售
int sellRecord(char *order, FILE *file)
{
GoodsMsg *temp = (GoodsMsg *)malloc(sizeof(GoodsMsg));
unsigned int partNumber;
unsigned int quantity;
float sellPrice; rewind(file);
//命令符合格式
if(sscanf(order, "sell %u , %u , %f\n", &partNumber, &quantity, &sellPrice) == 3) {
//查看数据更新位置
while (fread(temp, sizeof(GoodsMsg), 1, file)) {
//查找产品
if (temp->lineNum == partNumber) {
//定位到该条信息前,准备覆盖信息
fseek(file, -sizeof(GoodsMsg), SEEK_CUR);
temp -> totalPrice = (temp -> totalPrice) - quantity * (temp -> price);
temp -> quantity = (temp -> quantity) - quantity;
temp -> profit = temp -> profit + (sellPrice - temp -> price) * quantity;
fwrite(temp, sizeof(GoodsMsg), 1, file);
fflush(file);
return SUCCESS;
}
}
//其他情况都返回FAILED
}
return FAILED;
} //删除,只需将isDelete置为1
int delRecord(char *order, FILE *file)
{
GoodsMsg *temp = (GoodsMsg *)malloc(sizeof(GoodsMsg));
unsigned int partNumber; rewind(file);
//命令符合格式
if(sscanf(order, "delete %u\n", &partNumber) == 1) {
//查看数据更新位置
while (fread(temp, sizeof(GoodsMsg), 1, file)) {
//查找产品
if (temp->lineNum == partNumber) {
//定位到该条信息前,准备覆盖信息
fseek(file, -sizeof(GoodsMsg), SEEK_CUR);
temp -> isDeleted = 1;
fwrite(temp, sizeof(GoodsMsg), 1, file);
fflush(file);
return SUCCESS;
}
}
//其他情况都返回FAILED
}
return FAILED;
} //打印
int printPartRecord(char *order, FILE *file)
{
GoodsMsg *temp = (GoodsMsg *)malloc(sizeof(GoodsMsg));
unsigned int partNumber; rewind(file);
//命令符合格式
if(sscanf(order, "print %u\n", &partNumber) == 1) {
//查看数据更新位置
while (fread(temp, sizeof(GoodsMsg), 1, file)) {
//在未删除产品中查找
if (temp->lineNum == partNumber && temp -> isDeleted == 0) {
//打印信息
printf("\nid:%4u %u %.2f %.2f %20s\n", temp -> lineNum, temp -> quantity, temp -> price, temp -> totalPrice, temp -> description);
return SUCCESS;
}
}
//其他情况都返回FAILED
}
return FAILED;
} //打印所有
void printRecord(FILE *file)
{
GoodsMsg *temp = (GoodsMsg *)malloc(sizeof(GoodsMsg)); rewind(file);
printf("\nid quan price totalPric descprition\n");
//命令符合格式
while (fread(temp, sizeof(GoodsMsg), 1, file)) {
//打印所有未删除商品
if(temp -> isDeleted == 0){
printf("id:%-4u%-4u %.2f %.2f\t%-20s\n", temp -> lineNum, temp -> quantity, temp -> price, temp -> totalPrice, temp -> description);
}
}
printf("--------------------------------------------\n");
} //计算总价值
float totalPrice(FILE *file)
{
float totalPrice = 0;
GoodsMsg *temp = (GoodsMsg *)malloc(sizeof(GoodsMsg)); rewind(file);
//命令符合格式
while (fread(temp, sizeof(GoodsMsg), 1, file)) {
//打印信息
totalPrice += temp -> totalPrice;
} return totalPrice;
}

运行:

注意:如果wb+打开文件需要读取,那么在读取之前需要fflush或文件定位函数,fseek,fsetpos, rewind。如果rb+打开文件,需要写入,必须调用文件定位函数,fseek,fsetpos, rewind。

C和指针 第十五章 习题的更多相关文章

  1. C和指针 第十五章 二进制I/O

    二进制I/O 数据写入到文件效率最高的是用二进制形式写入,二进制输出避免了在数值转换为字符串过程中,所涉及的开销和精度损失,但而精致并非人眼所能阅读,所以这个技巧只有当数据被另一个程序按顺序读取才能使 ...

  2. C和指针 第十五章 文件I/O

    stdio.h中包含了声明FILE结构 struct _iobuf { char *_ptr; //文件输入的下一个位置 int _cnt; //当前缓冲区的相对位置 char *_base; //指 ...

  3. C和指针 第十六章 习题

    16.8 计算平均年龄 #include <stdlib.h> #include <stdio.h> #define MAX_LEN 512 int main() { int ...

  4. C和指针 第十五章 输入输出缓冲

    对于C,所有的I/O操作都只是简单的从程序移进或移出字节,这种字节流便成为流(stream),我们需要关心的只是创建正确的输出字节数据,以及正确的输入读取数据,特定的I/O设备细节都是对程序隐藏的. ...

  5. C和指针 第十五章 错误报告perror和exit

    15.1 错误报告 perror 任何一种程序都存在出错的可能,包括系统的函数库,当出现错误时,系统提示发生错误,标准库函数在一个外部整型变量中保存错误代码,然后把错误代码传给用户程序,提示错误原因. ...

  6. C和指针 第十四章 习题

    14.1 打印函数 #include <stdio.h> void print_ledger_long(){ printf("function print_ledger_long ...

  7. C++ Primer Plus学习:第十五章

    第十五章 友元.异常和其他 友元 友元类 表 0-1 class Tv { public: friend class Remote; } Remote类可以使用Tv的数据成员,Remote类在Tv类后 ...

  8. 【C++】《C++ Primer 》第十五章

    第十五章 面向对象程序设计 一.OOP:概述 面向对象程序设计(OOP)的核心思想是数据抽象.继承和动态绑定. 通过使用数据抽象,可以将类的接口和实现分离. 使用继承,可以定义相似的类型并对其相似关系 ...

  9. 15第十五章UDF用户自定义函数(转载)

    15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布

随机推荐

  1. 【教程】CDQ套CDQ——四维偏序问题

    前言 上一篇文章已经介绍了简单的CDQ分治,包括经典的二维偏序和三维偏序问题,还有带修改和查询的二维/三维偏序问题.本文讲介绍多重CDQ分治的嵌套,即多维偏序问题. 四维偏序问题       给定N( ...

  2. 【WPF】GridLengthAnimation

    参考 : http://zhidao.baidu.com public class GridLengthAnimation : AnimationTimeline { public static re ...

  3. CentOS安装Redis详细教程

    构建 Redis redis 目前没有官方 RPM 安装包,我们需要从源代码编译,而为了要编译就需要安装 Make 和 GCC. 如果没有安装过 GCC 和 Make,那么就使用 yum 安装. yu ...

  4. IOS跑马灯效果,实现文字水平无间断滚动

    ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController{ NSTimer ...

  5. Less的使用

    Less为css预处理器 首先先去下载一个koala编译器软件,然后运行打开 新建一个项目目录,在css文件夹中新建一个后缀为less的文件,然后拉入koala软件中,然后运行 ,你的css文件夹中就 ...

  6. python基础补漏-02-collection

    collection系列 [1]计数器 Counter import collections res = collections.Counter("34234sdfgs45tsaf1&quo ...

  7. c风格字符串

    1.字符数组截取 有当然有了,应均包含在<string.h>中. 有strncpy,strncat.可以帮你从任何位置,取得任意合法长度的字符串. 用法基本同strcpy,strcat. ...

  8. redis-内存异常 Redis is configured to save RDB snapshots解决

    连接reids获取数据时提示 Redis is configured to save RDB snapshots, but is currently not able to persist on di ...

  9. .技术参数图用pillow自动处理

    python 2.7 pillow 安装python2.7.10(自带pip),修改豆瓣源,下载pillow

  10. wordpress默认index主页选择Your Projects提示无法找到项目解决办法?

    wordpress_4.5.3默认index主页选择Your Projects下部署的项目发现报错无法找到目标解决办法: 1.其实细心的小伙伴已经发现问题出在哪里,跳转后链接地址发生了错误没有加loc ...