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。

posted @ 2016-09-11 23:51  xnuwu  阅读(424)  评论(0编辑  收藏  举报