我们回到control.c文件里。那么我们就可以利用g_pcontrol_input进行读取工作。当然这里有个学院派的做法,就是检测当前文件的长度,毕竟如果这个长度比BUF大,我们得认为不能处理嘛。后面有概念解决掉这个小问题。
鬼话:程序员,会一直和BUG打交道。错误、不足、BUG统称是BUG吧。我没说做斗争,是因为,本身系统设计,人为问题,总有不足,甚至这些不足是开发阶段造成的。例如上面这个典型的例子,我们暂时不支持大于4096的文件长度。什么都尽善尽美了,还有什么后续版本可以做呢?哈。
我们修改control.c的read_param_from_file 函数如下
static int read_param_from_file(char * filename){ FILE *fp; long int file_size; size_t read_size; __PRINT_FUNC(); fp = fopen(filename,"rt"); if (fp == 0) return 1; fseek( fp, 0L, SEEK_END ); file_size = ftell(fp); if (file_size >= CONTROL_INPUT_SIZE){ fclose(fp); return 2; } fseek(fp,0L,SEEK_SET); read_size = fread(g_pcontrol_input,sizeof(char),(size_t)file_size,fp); printf("file size is %ld,read is %ld !\n",file_size,read_size); fclose(fp); return 0; }
#define GET_FILE_SIZE(size,fp) do {long int pos = ftell(fp); fseek(fp,0L,SEEK_END);size = ftell(fp);fseek(fp,pos,SEEK_SET);}while(0) static int read_param_from_file(char * filename){ FILE *fp; long int file_size; long int read_size; __PRINT_FUNC(); fp = fopen(filename,"rt"); if (fp == 0) return 1; GET_FILE_SIZE(file_size,fp); if (file_size >= CONTROL_INPUT_SIZE){ fclose(fp); return 2; }
read_size = fread(g_pcontrol_input,sizeof(char),file_size,fp);
printf("file size is %ld,read is %ld !\n",file_size,read_size);
fclose(fp);
return 0;
}
#include <stdio.h> #include "define_attr.h" #include "control.h" #include "value.h" #define GET_FILE_SIZE(size,fp) do {long int pos = ftell(fp); fseek(fp,0L,SEEK_END);size = ftell(fp);fseek(fp,pos,SEEK_SET);}while(0) char filename[1024]; static long int buf_num = 0; static int split_line(void){ __PRINT_FUNC(); return 0; } static int split_token(void){ __PRINT_FUNC(); return 0; } static int check_grammar(void){ __PRINT_FUNC(); return 0; } static int set_param(void){ __PRINT_FUNC(); return 0; } static void read_param_default(void){ __PRINT_FUNC(); return; } static int read_param_from_file(char * filename){ FILE *fp; long int file_size; long int read_size; __PRINT_FUNC(); fp = fopen(filename,"rt"); if (fp == 0) return 1; GET_FILE_SIZE(file_size,fp); if (file_size >= CONTROL_INPUT_SIZE){ fclose(fp); return 2; }
buf_num = read_size = fread(g_pcontrol_input,sizeof(char),file_size,fp);
g_pcontrol_input[buf_num] = 0;
printf("file size is %ld,read is %ld !\n",file_size,read_size);
fclose(fp);
return 0;
}
void control(int flag){ if (flag){ read_param_from_file(filename); }else{ read_param_default(); } return; }
static int split_line(void){ int i;
__PRINT_FUNC();
i = 0;
while (i < buf_num){
if ((g_pcontrol_input[i] == 0xd) || (g_pcontorl_input[i] == 0xa)){
g_pcontrol_input[i] = 0;
}
i++;
}
return 0;
}
#define dNEXT_LINE 0xa #define dRETURN 0xd
#define CHECK_LINES(p,i,lines) do {lines += (p[i] == dNEXT_LINE);}while (0)
static int split_line(char *pbuf){ int i;
int lines = 0; __PRINT_FUNC(); i = 0;
while (i < buf_num){
CHECK_LINES(pbuf,i,lines);
if ((pbuf[i] == dNEXT_LINE) || (pbuf[i] == dRETURN)){
pbuf[i] = 0;
}
i++;
}
printf("the lines is %d\n",lines);
return lines;
}
鬼话:通常,和外部打交道的,例如读取文件,其逻辑本身就对资源具备独占性,因此可以直接使用全局存储空间,而内部函数,要保证代码的可复用性,应尽可能的使用局部存储存储空间。这就是为什么在split_line中使用pbuf,在上面读取文件中,使用全局存储空间的原因。#define CHECK_ALPHA(c) (((c) != dSPACE_KEY) && ((c) != dTAB_KEY))
static int split_token(char *pline,char *ppos[]){ int tokens = 0;
__PRINT_FUNC();
while (*pline){
if (CHECK_ALPHA(pline[0])){
ppos[tokens++] = pline;
pline++;
while (CHECK_ALPHA(pline[0])){
if (pline[0] == 0){
goto LABEL_return_split_token;
}
pline++;
}
}
pline[0] = 0;
pline++;
}
LABEL_return_split_token: printf("the tokens is %d !\n",tokens);
return tokens; }
static int split_line(char *pbuf){ int i;
int lines = 0; char *pline = pbuf; __PRINT_FUNC(); i = 0;
while (i < buf_num){
CHECK_LINES(pbuf,i,lines);
if ((pbuf[i] == dNEXT_LINE) || (pbuf[i] == dRETURN)){
pbuf[i] = 0;
printf("%s \n",pline);
split_token(pline,s_ptoken_pos);
pline = pbuf + i+1;
}
i++;
}
printf("the lines is %d\n",lines);
return 0;
}
static int split_line(char *pbuf){ int i;
int lines = 0; char *pline = pbuf; __PRINT_FUNC(); i = 0;
while (i < buf_num){
CHECK_LINES(pbuf,i,lines);
if (pbuf[i] == dNEXT_LINE){
pbuf[i] = 0;
printf("%s \n",pline);
split_token(pline,s_ptoken_pos);
pline = pbuf + i+1;
}else if (pbuf[i] == dRETURN){
pbuf[i] = 0;
pline = pbuf+i+1;
}
i++;
}
printf("the lines is %d\n",lines);
return 0;
}
while (*pline){ if (CHECK_ALPHA(pline[0])){ ppos[tokens++] = pline; pline++; while (CHECK_ALPHA(pline[0])){ if (pline[0] == 0){ goto LABEL_return_split_token; } pline++; }
} pline[0] = 0; pline++; }
#define TOKEN_MAX_NUM 10 static char *s_ptoken_pos[TOKEN_MAX_NUM];
static int split_token(char *pline,char *ppos[]){ int tokens = 0;
__PRINT_FUNC();
while ((*pline) && (tokens< TOKEN_MAX_NUM )){
if (CHECK_ALPHA(pline[0])){
ppos[tokens++] = pline;
pline++;
while (CHECK_ALPHA(pline[0])){
if (pline[0] == 0){
goto LABEL_return_split_token;
}
pline++;
}
}
pline[0] = 0;
pline++;
}
LABEL_return_split_token: printf("the tokens is %d !\n",tokens);
return tokens; }
static int split_token(void){ __PRINT_FUNC(); return 0; }
static int split_token(char *pline){ int tokens = 0; while (pline){ pline++; } return 0; }
static int split_token(void){ int tokens = 0; __PRINT_FUNC(); return 0; }
static int split_token(char *pline){ int tokens = 0; __PRINT_FUNC(); return 0; }
static int split_token(char *pline){ int tokens = 0; __PRINT_FUNC(); while (pline){
}
return 0;
}
static int split_token(char *pline){ int tokens = 0; __PRINT_FUNC(); while (pline){ pline++; } return 0; }
static int split_line(char *pbuf){ int i;
int lines = 0; char *pline = pbuf; __PRINT_FUNC(); i = 0;
while (i < buf_num){
CHECK_LINES(pbuf,i,lines);
if (pbuf[i] == dNEXT_LINE){
int tokens;
pbuf[i] = 0;
printf("%s \n",pline);
tokens = split_token(pline,s_ptoken_pos);
printf("%d\n",tokens);
check_grammar(tokens,s_ptoken_pos);
pline = pbuf + i+1;
}else if (pbuf[i] == dRETURN){
pbuf[i] = 0;
pline = pbuf+i+1;
}
i++;
}
printf("the lines is %d\n",lines);
return 0;
}
static int check_grammar(int argc,char *argv[]){ int value; __PRINT_FUNC(); if (argc != 3){ return 1; } if ((strcmp(argv[0],"height") != 0) || (strcmp(argv[0],"weight") != 0)|| (strcmp(argv[0],"mode") != 0)){ return 2; } if (strcmp(argv[1],"=") != 0){ return 3; } value = atoi(argv[2]); printf("%s -> %d\n",argv[0],value); return 0; }
static int set_param(int mode,int value){ __PRINT_FUNC(); switch (mode){ case HEIGHT_PARAM: s_height_param = value; printf("%s -> %d\n",PARAM_STR0,value); break; case WIDTH_PARAM: s_width_param = value; printf("%s -> %d\n",PARAM_STR1,value); break; case MODE_PARAM:s_mode_param = value; printf("%s -> %d\n",PARAM_STR2,value); break; default: printf("mode is error!\n"); } return 0; }
static int check_grammar(int argc,char *argv[]){ int value; int mode = -1; __PRINT_FUNC(); if (argc != 3){ return 1; }
if ((strcmp(argv[0],PARAM_STR0) == 0)){
mode = 0;
}else if ((strcmp(argv[0],PARAM_STR1) == 0)){
mode = 1;
}else if ((strcmp(argv[0], PARAM_STR2) == 0)){
mode = 2;
}else {
return 2;
}
if (strcmp(argv[1],"=") != 0){
return 3;
}
value = atoi(argv[2]);
set_param(mode,value);
return 0;
}
#define PARAM_STR0 "height" #define PARAM_STR1 "width" #define PARAM_STR2 "mode" enum{ HEIGHT_PARAM, WIDTH_PARAM, MODE_PARAM, MAX_PARAM }; static int s_height_param; static int s_width_param; static int s_mode_param;
这些问题我们放到下一篇介绍。目前咱们已经顺利的完成了对一个文本文件参数的读取工作。我更希望先不要深究代码的性能指令,对于新手,而是多思考,一个任务,如何分解,并逐步实现。
有点没得要领
其实指针,以及C语言的其他基本类型都一回事儿吧,就是一段内存,再加上对内存使用方法的解释。
类型转换就是转换一下内存使用的方法。
只不过指针里面保存的是内存地址而已。抛开一些表面的概念,以底层一点的角度去理解,还算简单的。
当然具体使用的时候,有什么技巧,什么陷阱,容易弄错的地方,经验还是很有用的。
######有点没得要领
其实指针,以及C语言的其他基本类型都一回事儿吧,就是一段内存,再加上对内存使用方法的解释。
类型转换就是转换一下内存使用的方法。
只不过指针里面保存的是内存地址而已。抛开一些表面的概念,以底层一点的角度去理解,还算简单的。
当然具体使用的时候,有什么技巧,什么陷阱,容易弄错的地方,经验还是很有用的。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。