Define tag cannot set a null value' error

博客指出定义标签值value不能为空,常被忽略且较难发现的错误原因是数据库某些字段为空,重点围绕解决该数据库字段为空引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解决:定义标签值value不能为空,常忽略一点且为较难发现的是数据库的某些字段为空而造成错误
#ifndef _COM_ARGS_H_ #define _COM_ARGS_H_ #ifdef __cplusplus extern "C" { #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #define ARGS_TYPE_MANDATORY (1<<0) /* mandatory or not */ #define COM_ARGS_VAL_TYPE_NONE (0<<1) /* no value */ #define ARGS_TYPE_INTEGER (10<<1) /* integer type value */ #define ARGS_TYPE_STRING (20<<1) /* string type value */ #define COM_ARGS_GET_CMD_OPT_VAL_TYPE(x) ((x) & ~ARGS_TYPE_MANDATORY) #define COM_ARGS_NO_KEY (127) typedef struct _COM_ARGS_OPTION { char key; /* option keyword. ex) -f */ char key_long[32]; /* option long keyword, ex) --file */ int val_type; /* value type */ int * flag; /* flag to setting or not */ void * val; /* actual value */ char desc[512]; /* description of option */ } COM_ARGS_OPTION; static int com_args_search_long_arg(COM_ARGS_OPTION * opts, const char * argv) { int oidx = 0; COM_ARGS_OPTION * o; o = opts; while(o->key != 0) { if(!strcmp(argv, o->key_long)) { return oidx; } oidx++; o++; } return -1; } static int com_args_search_short_arg(COM_ARGS_OPTION * ops, const char argv) { int oidx = 0; COM_ARGS_OPTION * o; o = ops; while(o->key != 0) { if(o->key != COM_ARGS_NO_KEY && o->key == argv) { return oidx; } oidx++; o++; } return -1; } static int com_args_read_value(COM_ARGS_OPTION * ops, const char * argv) { if(argv == NULL) return -1; if(argv[0] == '-' && (argv[1] < '0' || argv[1] > '9')) return -1; switch(COM_ARGS_GET_CMD_OPT_VAL_TYPE(ops->val_type)) { case ARGS_TYPE_INTEGER: *((int*)ops->val) = atoi(argv); break; case ARGS_TYPE_STRING: strcpy((char*)ops->val, argv); break; default: return -1; } return 0; } static int com_args_get_help(COM_ARGS_OPTION * ops, int idx, char * help) { int optional = 0; char vtype[32]; COM_ARGS_OPTION * o = ops + idx; switch(COM_ARGS_GET_CMD_OPT_VAL_TYPE(o->val_type)) { case ARGS_TYPE_INTEGER: strcpy(vtype, "INTEGER"); break; case ARGS_TYPE_STRING: strcpy(vtype, "STRING"); break; case COM_ARGS_VAL_TYPE_NONE: default: strcpy(vtype, "FLAG"); break; } optional = !(o->val_type & ARGS_TYPE_MANDATORY); if(o->key != COM_ARGS_NO_KEY) { sprintf(help, " -%c, --%s [%s]%s\n : %s", o->key, o->key_long, vtype, (optional) ? " (optional)" : "", o->desc); } else { sprintf(help, " --%s [%s]%s\n : %s", o->key_long, vtype, (optional) ? " (optional)" : "", o->desc); } return 0; } static int com_args_get_arg(COM_ARGS_OPTION * ops, int idx, char * result) { char vtype[32]; char value[512]; COM_ARGS_OPTION * o = ops + idx; switch(COM_ARGS_GET_CMD_OPT_VAL_TYPE(o->val_type)) { case ARGS_TYPE_INTEGER: strcpy(vtype, "INTEGER"); sprintf(value, "%d", *((int*)o->val)); break; case ARGS_TYPE_STRING: strcpy(vtype, "STRING"); sprintf(value, "%s", (char*)o->val); break; case COM_ARGS_VAL_TYPE_NONE: default: strcpy(vtype, "FLAG"); sprintf(value, "%d", *((int*)o->val)); break; } if(o->flag != NULL && (*o->flag)) { strcat(value, " (SET)"); } else { strcat(value, " (DEFAULT)"); } sprintf(result, " -%c(--%s) = %s\n : %s", o->key, o->key_long, value, o->desc); return 0; } static int com_parse_cfg(FILE * fp, COM_ARGS_OPTION * ops) { char * parser; char line[4096] = "", tag[50] = "", val[4096] = ""; int oidx; while(fgets(line, sizeof(line), fp)) { parser = strchr(line, '#'); if (parser != NULL) { *parser = '\0'; } parser = strtok(line, ": \t"); // find the parameter name if (parser == NULL) { continue; } strcpy(tag, parser); parser = strtok(NULL, ":"); // skip the colon parser = strtok(NULL, " \t\n"); if(parser == NULL) continue; strcpy(val, parser); oidx = com_args_search_long_arg(ops, tag); if (oidx < 0) { printf("\nError in configuration file: \"%s\" is not a valid command!\n", tag); return -1; } if(COM_ARGS_GET_CMD_OPT_VAL_TYPE(ops[oidx].val_type) != COM_ARGS_VAL_TYPE_NONE) { if(com_args_read_value(ops + oidx, val)) continue; } else { *((int*)ops[oidx].val) = 1; } *ops[oidx].flag = 1; } return 0; } static int com_parse_cmd(int argc, const char * argv[], COM_ARGS_OPTION * ops, int * idx) { int aidx; /* arg index */ int oidx; /* option index */ aidx = *idx + 1; if(aidx >= argc || argv[aidx] == NULL) goto NO_MORE; if(argv[aidx][0] != '-') goto ERR; if(argv[aidx][1] == '-') { /* long option */ oidx = com_args_search_long_arg(ops, argv[aidx] + 2); if (oidx < 0) { printf("\nError in command: \"%s\" is not a valid command!\n", argv[aidx]); goto ERR; } } else if(strlen(argv[aidx]) == 2) { /* short option */ oidx = com_args_search_short_arg(ops, argv[aidx][1]); if (oidx < 0) { printf("\nError in command: \"%s\" is not a valid command!\n", argv[aidx]); goto ERR; } } else { printf("\nError in command: \"%s\" is not a valid command!\n", argv[aidx]); goto ERR; } if(COM_ARGS_GET_CMD_OPT_VAL_TYPE(ops[oidx].val_type) != COM_ARGS_VAL_TYPE_NONE) { if (aidx + 1 >= argc) { printf("\nError in command: \"%s\" setting is incorrect!\n", argv[aidx]); goto ERR; } if (com_args_read_value(ops + oidx, argv[aidx + 1])) { printf("\nError in command: \"%s\" setting is incorrect!\n", argv[aidx]); goto ERR; } *idx = *idx + 1; } else { *((int*)ops[oidx].val) = 1; } *ops[oidx].flag = 1; *idx = *idx + 1; return ops[oidx].key; NO_MORE: return 0; ERR: return -1; } static int com_args_parse_all(int argc, const char * argv[], COM_ARGS_OPTION * ops) { int i, ret = 0, idx = 0; COM_ARGS_OPTION *o; const char *fname_cfg = NULL; FILE *fp; /* config file parsing */ for(i = 1; i < argc; i++) { if(!strcmp(argv[i], "--config")) { if(i + 1 < argc) { fname_cfg = argv[i + 1]; break; } } } if(fname_cfg) { fp = fopen(fname_cfg, "r"); if (fp == NULL) { printf("\nError: Cannot open %s\n", fname_cfg); return -1; } if(com_parse_cfg(fp, ops)) { fclose(fp); return -1; /* config file error */ } fclose(fp); } /* command line parsing */ while(1) { ret = com_parse_cmd(argc, argv, ops, &idx); if(ret <= 0) break; } /* check mandatory argument */ o = ops; while(o->key != 0) { if(o->val_type & ARGS_TYPE_MANDATORY) { if(*o->flag == 0) { /* not filled all mandatory argument */ return o->key; } } o++; } return ret; } static int com_args_parse_int_x_int(char * str, int * num0, int * num1) { char str0_t[64]; int i, cnt0, cnt1; char * str0, *str1 = NULL; str0 = str; cnt1 = (int)strlen(str); /* find 'x' */ for(i = 0; i < (int)strlen(str); i++) { if(str[i] == 'x' || str[i] == 'X') { str1 = str + i + 1; cnt0 = i; cnt1 = cnt1 - cnt0 - 1; break; } } /* check malformed data */ if(str1 == NULL || cnt0 == 0 || cnt1 == 0) return -1; for(i = 0; i < cnt0; i++) { if(str0[i] < 0x30 || str0[i] > 0x39) return -1; /* not a number */ } for(i = 0; i < cnt1; i++) { if(str1[i] < 0x30 || str1[i] > 0x39) return -1; /* not a number */ } strncpy(str0_t, str0, cnt0); str0_t[cnt0] = '\0'; *num0 = atoi(str0_t); *num1 = atoi(str1); return 0; } #ifdef __cplusplus } #endif #endif /*_COM_ARGS_H_ */
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值