C和指针 第十五章 习题

时间:2023-03-09 17:39:39
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文件内容:

C和指针 第十五章 习题

运行:

C和指针 第十五章 习题

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,运行:

C和指针 第十五章 习题

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;
}

运行:

C和指针 第十五章 习题

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;
}

运行:

C和指针 第十五章 习题

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