在C语言中,我们经常碰到想要处理命令行的情况。当往往由于C语言字符串比较难处理,最终出现各种奇怪的错误。现已算法指令为例,说明C语言命令行处理的框架。算法指令如下图所示:
算法 | 指令 |
---|---|
加法 | ADD op1 op2 |
减法 | SUB op1 op2 |
乘法 | MUL op1 op2 |
除法 | DIV op1 op2 |
预期效果: 程序等待用户输入用户指令,当程序键入算法指令后,输出正确的结果;如果出现非法操作,则输出响应的出错信息。
在main函数中,处理程序的代码框架,do_line处理由命令行获取的一行数据数据:
1 while (fgets(buf, MAXLINE, stdin) != NULL) 2 { 3 if(do_line(buf)) 4 break; 5 }
当do_line返回非0值时, 代表程序退出;但返回1时, 程序继续运行。注意fgets函数获取当前行的数据会包含’\n’,因此buf字符串末尾包含’\n’,’\0’两个字符。对每一行的处理在do_line_core函数中定义:
1 flag = get_token(cmd, line, &pos); 2 if (flag) {return 0;} //非法命令,重新输入 3 if (strcmp(“q”, cmd) == 0) return 1; //退出程序 4 5 if(strcmp(“add”, cmd) == 0) ... 6 else if(strcmp(“sub”, cmd) == 0) ... 7 else if(strcmp(“mul”, cmd) == 0) ... 8 else if(strcmp(“div”, cmd) == 0) ... 9 else return 0; //未知命令,重新输入
get_token获取下一个命令或操作数,其中pos代表读取的当前地址。当获取的命令为非法命令(为空)时,返回1;否则返回0。
1 int get_token(char *token, char *line, int *pos) 2 { 3 /* 保存当前的token指针 */ 4 char *token_saved = token; 5 /* 去除开头的空格符号 */ 6 while (isspace(line[*pos]) && line[*pos]) (*pos)++; 7 /* 获取pos位置开始的下一条命令或操作符 */ 8 while (!isspace(line[*pos]) && line[*pos]) 9 { 10 *token = line[*pos]; 11 token++; 12 (*pos)++; 13 } 14 *token = ‘\0’; 15 /* 字符串为空,返回1 */ 16 if (strcmp(token_saved, “”) == 0) return 1; 17 return 0; 18 }
简化:
* 如果使用全局变量来描述每一行的数据,可以减少函数的参数。
* 如果在*nix环境下,可以使用setjmp, longjmp来简化处理逻辑1。
- 《UNIX环境高级编程》第7章, “setjmp函数和longjmp函数“。 ?
时间: 2024-10-18 03:51:54