C和指针 第十五章 习题
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和指针 第十五章 习题的更多相关文章
- C和指针 第十五章 二进制I/O
二进制I/O 数据写入到文件效率最高的是用二进制形式写入,二进制输出避免了在数值转换为字符串过程中,所涉及的开销和精度损失,但而精致并非人眼所能阅读,所以这个技巧只有当数据被另一个程序按顺序读取才能使 ...
- C和指针 第十五章 文件I/O
stdio.h中包含了声明FILE结构 struct _iobuf { char *_ptr; //文件输入的下一个位置 int _cnt; //当前缓冲区的相对位置 char *_base; //指 ...
- C和指针 第十六章 习题
16.8 计算平均年龄 #include <stdlib.h> #include <stdio.h> #define MAX_LEN 512 int main() { int ...
- C和指针 第十五章 输入输出缓冲
对于C,所有的I/O操作都只是简单的从程序移进或移出字节,这种字节流便成为流(stream),我们需要关心的只是创建正确的输出字节数据,以及正确的输入读取数据,特定的I/O设备细节都是对程序隐藏的. ...
- C和指针 第十五章 错误报告perror和exit
15.1 错误报告 perror 任何一种程序都存在出错的可能,包括系统的函数库,当出现错误时,系统提示发生错误,标准库函数在一个外部整型变量中保存错误代码,然后把错误代码传给用户程序,提示错误原因. ...
- C和指针 第十四章 习题
14.1 打印函数 #include <stdio.h> void print_ledger_long(){ printf("function print_ledger_long ...
- C++ Primer Plus学习:第十五章
第十五章 友元.异常和其他 友元 友元类 表 0-1 class Tv { public: friend class Remote; } Remote类可以使用Tv的数据成员,Remote类在Tv类后 ...
- 【C++】《C++ Primer 》第十五章
第十五章 面向对象程序设计 一.OOP:概述 面向对象程序设计(OOP)的核心思想是数据抽象.继承和动态绑定. 通过使用数据抽象,可以将类的接口和实现分离. 使用继承,可以定义相似的类型并对其相似关系 ...
- 15第十五章UDF用户自定义函数(转载)
15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布
随机推荐
- 【教程】CDQ套CDQ——四维偏序问题
前言 上一篇文章已经介绍了简单的CDQ分治,包括经典的二维偏序和三维偏序问题,还有带修改和查询的二维/三维偏序问题.本文讲介绍多重CDQ分治的嵌套,即多维偏序问题. 四维偏序问题 给定N( ...
- 【WPF】GridLengthAnimation
参考 : http://zhidao.baidu.com public class GridLengthAnimation : AnimationTimeline { public static re ...
- CentOS安装Redis详细教程
构建 Redis redis 目前没有官方 RPM 安装包,我们需要从源代码编译,而为了要编译就需要安装 Make 和 GCC. 如果没有安装过 GCC 和 Make,那么就使用 yum 安装. yu ...
- IOS跑马灯效果,实现文字水平无间断滚动
ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController{ NSTimer ...
- Less的使用
Less为css预处理器 首先先去下载一个koala编译器软件,然后运行打开 新建一个项目目录,在css文件夹中新建一个后缀为less的文件,然后拉入koala软件中,然后运行 ,你的css文件夹中就 ...
- python基础补漏-02-collection
collection系列 [1]计数器 Counter import collections res = collections.Counter("34234sdfgs45tsaf1&quo ...
- c风格字符串
1.字符数组截取 有当然有了,应均包含在<string.h>中. 有strncpy,strncat.可以帮你从任何位置,取得任意合法长度的字符串. 用法基本同strcpy,strcat. ...
- 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 ...
- .技术参数图用pillow自动处理
python 2.7 pillow 安装python2.7.10(自带pip),修改豆瓣源,下载pillow
- wordpress默认index主页选择Your Projects提示无法找到项目解决办法?
wordpress_4.5.3默认index主页选择Your Projects下部署的项目发现报错无法找到目标解决办法: 1.其实细心的小伙伴已经发现问题出在哪里,跳转后链接地址发生了错误没有加loc ...