密码强度检测工具中getopt的optarg为空,无法检测-f选项未提供文件名的问题
解决
getopt处理-f选项时未提供文件名的检测问题 你的问题核心在于没有正确处理getopt返回的选项缺少参数的情况,同时代码里还有个容易忽略的break缺失问题,这两个问题加起来导致你没法捕获用户只输入-f却不跟文件名的错误。
咱们一步步来修正:
1. 理解getopt的错误返回规则
你用的optstring是:hf:,开头的冒号是告诉getopt:当选项缺少必要参数时,返回:而不是默认的?,同时optopt会存储对应的选项字符(这里就是'f')。但你的代码里只处理了case '?',没处理case ':',所以这种缺少参数的情况就被漏掉了。
2. 修复代码中的两个关键问题
问题1:case 'f'缺少break
你当前的case 'f'分支执行完后,会直接落到case '?'里,这会导致正常使用-f带参数时,也会触发错误提示,这肯定不对,必须给每个case加上break。
问题2:添加case ':'处理缺少参数的情况
当用户输入-f却不提供文件名时,getopt会返回:,此时我们可以针对性地输出错误信息,比如“选项-f需要一个文件名参数”。
额外优化:检测filename是否为空
即便前面的逻辑处理了,也可以在后续使用filename前加一层空值检测,双重保险。
修改后的完整代码片段
int main(int argc, char *argv[]) { //for getopt int option; char *filename = NULL; // 初始化NULL,避免野指针 int fflag = 0; char *password = argv[1]; // 补充密码参数的定义,原代码中未声明 //checks if no args is given and prints out the help page if(argc == 1){ help(); return 0; } while((option = getopt(argc, argv, ":hf:")) != -1){ switch(option){ case 'h': help(); return 0; case 'f': //read file name from -f flag filename = optarg; fflag = 1; break; // 必须加break,避免fall through到其他case case '?': fprintf(stderr, "Unknown option -%c\n", optopt); return 1; case ':': // 处理选项缺少参数的情况 if(optopt == 'f'){ fprintf(stderr, "Option -%c requires a .txt filename as an argument\n", optopt); } else { fprintf(stderr, "Option -%c requires an argument\n", optopt); } return 1; } } //check if -f flag is used if(fflag == 1){ // 额外检测filename是否为空,双重保险 if(filename == NULL){ fprintf(stderr, "Option -f requires a .txt filename as an argument\n"); return 1; } int errorcode = file(filename, password); if(errorcode == 1){ fprintf(stderr,"Filename must be of .txt extension\n"); } else if ( errorcode == 2){ fprintf(stderr,"File not found or not able to open\n"); } else if (errorcode == 3){ fprintf(stderr,"Password not found in wordlist\n"); } else if (errorcode == 0){ printf("Password found in word list\n"); } return 0; } // 补充原代码中处理密码强度的逻辑 return 0; }
测试验证
当用户输入./password_checker abc -f时,程序会触发case ':'分支,输出错误提示并退出,完美解决你之前无法检测的问题。
内容的提问来源于stack exchange,提问作者Pranav Suresh
相关产品推荐
相关产品推荐

