/*------------------------mini_tool小工具系列 numconv.cc----------------------- Name: numconv.cyx 描述: 数值转换小工具, 用于将标准输入的 "十六进制/十进制/二进制" 数值互为转换. 方便其他程序设计中的 "位状态" 考虑. 作者: 任逍 |2002.04.21. 版权: GNU General Public License (GPL) ------------------------------------------------------------------------------*/ #include #include #include #include #include #include #include char bin_string[sizeof(long int) * 8 + 1]; void get_help(char* program_name); void get_version(char* program_name); char* puts_bin_string(char* bin_string, const long int value); bool test_chars(char* parameter, int num_system); int main(int argc, char** argv) { // 初步检测命令行参数. if (argc == 1) { printf("Please try -h or --help for help!\n"); return 0; } if ( (! strcmp(argv[1], "-h")) || (! strcmp(argv[1], "--help")) ) { get_help(argv[0]); return 0; } if ( (! strcmp(argv[1], "-V")) || (! strcmp(argv[1], "--version")) ) { get_version(argv[0]); return 0; } // 检测初始化环境变量 "NUMCONV_IN" 和 "NUMCONV_OUT". char* penv_in = NULL; char* penv_out = NULL; penv_in = getenv("NUMCONV_IN"); if ( (penv_in == NULL ) || (!strcmp(penv_in, "")) ) { printf(" Please export NUNCONV_IN to environment!\n OR try -h/--help for help.\n"); return -1; } penv_out = getenv("NUMCONV_OUT"); if ( (penv_out == NULL ) || (!strcmp(penv_out, "")) ) { printf(" Please export NUNCONV_OUT to environment!\n OR try -h/--help for help.\n"); return -1; } // 查看程序环境变量. if ( (!strcmp(argv[1], "-s")) ) { printf("NUMCONV_IN=\t%s\n", getenv("NUMCONV_IN")); printf("NUMCONV_OUT=\t%s\n", getenv("NUMCONV_OUT")); return 0; } // 按进制转换数据并显示(标准输出). long int conv_value; char* end_chars = NULL; int conv_in = atoi(getenv("NUMCONV_IN")); int conv_out = atoi(getenv("NUMCONV_OUT")); for (int iB = 1; iB < argc; iB ++) { if (! test_chars(argv[iB], conv_in)) { fprintf(stderr, "Invalid chars!\t-> %s\n", argv[iB]); printf("xxx\n"); // 待转换字符串首字符即不合法. 打印 "xxx" 作标示. continue; } if ( ((conv_value = strtol(argv[iB], &end_chars, conv_in) ) == LONG_MAX) || ((conv_value = strtol(argv[iB], &end_chars, conv_in) ) == LONG_MIN) ) { // 数值字符串超出long类型范围, 打印 "???" 作标示. fprintf(stderr, "Overflow or Underflow of:\t%s\n", argv[iB]); printf("???\n"); continue; } if ( (end_chars != NULL) && (strcmp(end_chars, "")) ) { // 在标准错误输出设备指出不能转换的非法字符. fprintf(stderr, "Spare chars of string end!\t-> %s\n", end_chars); end_chars = NULL; } switch (conv_out) { // 格式化显示转换后的数据. case 0: case 10: printf("%d\n", conv_value); break; case 8: printf("%#o\n", conv_value); break; case 16: printf("%#x\n", conv_value); break; case 2: printf("%s\n", puts_bin_string(bin_string, conv_value)); break; default: printf("Please set NUMCONV_OUT for correct.\n"); printf("Please tyt -h or --help for help!\n"); return -1; } } return 0; // 数值转换结束. } // 程序使用帮助函数. void get_help(char* pname) { printf("-----------------------------------------------------------------------------\n"); printf("Usage: %s [option] [number_chars ...]\n", pname); printf("(用法: %s [选项] [待处理数据字符串...]\n", pname); printf("\n描 述:\n"); printf(" 通过设定数据进制环境变量 \"NUMCONV_IN\" 和 \"NUMCONV_OUT\"转换从命令行传\n"); printf(" 入的数据字符串. 支持 \"二进制/八进制/十进制/十六进制\" 的任意互转.\n"); printf(" 转换后的数据送到标准输出.\n"); printf("\n选 项:\n"); printf(" -h|--help 显示此帮助列表.\n"); printf(" -V|--version 显示程序版本及相关说明.\n"); printf("\n注 意!\n"); printf(" 1. 使用前请先设定环境变量! 如\"export NUMCONV_IN=10\" ->设定输入数据为十\n"); printf(" 进制方式, \"export NUMCONV_OUT=16\" ->设定输出为十六进制.\n"); printf(" 2. 待处理数据字符串字符应是符合相应进制规定的字符, 如十六进制的a-f/A-F.\n"); printf(" 3. 程序可处理以空格/TAB分隔的多个数据字串(转换数据时无选项字符)\n"); printf(" 4. 在转换中碰到不能转换的非法字符, 程序打印已转换的数据, 并在标准错误输\n"); printf(" 出打印剩下的非法字串.\n"); printf(" 5. 若转换一开始就碰到非法字符, 程序打印 'xxxx' 字串以作标示, 并在标准错\n"); printf(" 误输出打印该字串.\n"); printf(" 6. 若碰到超出long数据类型范围的字串, 程序将其打印为 '???'.\n"); printf("\n错误反馈:\n"); printf(" 非常欢迎您的错误信息/报告反馈! 请将出现错误的前后情形描述得尽量详细些, \n"); printf(" 以方便本人的分析和判断, 解决您的问题(当然更是程序本身的问题!).\n"); printf(" 信息反馈地址: E-Mail: cyhouser@163.com 谢谢!\n"); printf("-----------------------------------------------------------------------------\n"); } // 二进制字符串显示函数. char* puts_bin_string(char* bin_string, const long int conv_value) { // 采用 "位检测" 循环赋值字符 '1' 或 '0'. int tmp_length = (sizeof(long int) * 8); long int tmp_value = conv_value; for (int i3 = tmp_length - 1; i3 >= 0; i3 --) { if (tmp_value & 1) bin_string[i3] = '1'; else bin_string[i3] = '0'; tmp_value = tmp_value >> 1; } bin_string[tmp_length] = '\0'; return bin_string; } // 显示程序版本号及其版权等说明. void get_version(char* name) { printf(" Name: %s\n", name); printf(" Version: 0.1-0\n"); printf(" License: GNU General Public License (GPL)\n"); printf(" Author: ZhongHui-Huang of Chinese.\n"); printf(" TimeFrom: 2002.04.27.\n"); } // 检测待转换字符串首字符(除'-'号外)是否合法. (包括 '0x?' 式的十六进制值) bool test_chars(char* param, int num_system) { int test_char[3]; int choice = num_system; if (!param || param[0] == '\0') return false; if (param[0] == '-') { if ( (test_char[0] = param[1]) != 0 ) if ( (test_char[1] = param[2]) != 0 ) if ( (test_char[2] = param[3]) != 0 ) ; } else { if ( (test_char[0] = param[0]) != 0 ) if ( (test_char[1] = param[1]) != 0 ) if ( (test_char[2] = param[2]) != 0 ) ; } switch (choice) { case 0: if ( (isdigit(test_char[0]) && test_char[1] != 'x') || ( (test_char[0] == '0') && (test_char[1] == 'x') && isxdigit(test_char[2]) ) ) return true; break; case 2: if ( (test_char[0] == '0') || (test_char[0] == '1') ) return true; break; case 8: if ( isdigit(test_char[0]) && ( test_char[0] < '8' ) ) return true; break; case 10: if ( isdigit(test_char[0]) ) return true; break; case 16: if ( isxdigit(test_char[0]) ) return true; break; default: break; } return false; }