C语言密码强度验证程序问题:level2函数返回值异常及数字/特殊字符计数失效
Hey there! Let's break down the issues in your code one by one—you're close, just a few key fixes needed:
1. Global vs Local Variable Conflict (The Root Cause of return 0 Issue)
You declared a global param variable at the top of your code, but in main you created a local param variable with int param = atoi(argv[2]);. The level2 function is using the global param, which defaults to 0 since it's never assigned a value. That means none of the if(param == ...) conditions in level2 are triggered, so the function always falls through to the final return 0.
Fix:
- Delete the global
paramandlevelvariables. Instead, pass these values as arguments to your validation functions. - Also, stop using global variables for counters like
lowerCaseLetterFound—these should be initialized inside each function, otherwise they'll retain values from previous calls and mess up your counts.
2. Duplicate fgets Calls Break Input Reading
When you run level==2 logic, you first call level1(), which reads the input from stdin using fgets. By the time you call level2(), there's no input left to read—fgets returns NULL, so the counting loop never runs. That's why your number/special character counters aren't working.
Fix:
- Read the input once in
main, store it in a local variable, and pass that string to all your validation functions instead of having each function read fromstdin.
3. Redundant level1() Calls
In your level==2 block, you call level1() twice: once just to run it, then again in the if condition. This is unnecessary, and it also wastes input (since the first call already reads the input).
Fixed Code Example
Here's how to rewrite your code to fix all these issues:
#include <stdio.h> #include <stdlib.h> #include <ctype.h> // Helper function to count character types (avoids repeating code) void count_chars(const char *str, int *lower, int *upper, int *number, int *special) { *lower = 0; *upper = 0; *number = 0; *special = 0; for (int i = 0; str[i] != '\0' && str[i] != '\n'; i++) { if (islower(str[i])) { (*lower)++; } else if (isupper(str[i])) { (*upper)++; } else if (isdigit(str[i])) { (*number)++; } else { (*special)++; } } } int level1(const char *password) { int lower, upper, number, special; count_chars(password, &lower, &upper, &number, &special); return (lower >= 1 && upper >= 1) ? 1 : 0; } int level2(const char *password, int param) { int lower, upper, number, special; count_chars(password, &lower, &upper, &number, &special); // First pass level1's requirement if (!(lower >= 1 && upper >= 1)) { return 0; } // Handle param cases with cleaner logic switch(param) { case 1: case 2: return 1; // Already meets level1, so passes case 3: return (number >= 1 || special >= 1) ? 1 : 0; default: // param >=4 return (number >= 1 && special >= 1) ? 1 : 0; } } int main(int argc, const char *argv[]) { // Validate input arguments first if (argc != 3) { printf("Usage: %s <LEVEL> <PARAM>\n", argv[0]); printf("LEVEL must be 1-4, PARAM must be a positive integer.\n"); return 1; } int level = atoi(argv[1]); int param = atoi(argv[2]); if (level < 1 || level > 4) { printf("Level must be 1 through 4.\n"); return 1; } if (param <= 0) { printf("Parameter is not a full positive number.\n"); return 1; } // Read password once char password[100]; printf("Enter your password: "); if (fgets(password, 100, stdin) == NULL) { printf("Error reading input.\n"); return 1; } // Run validation based on level if (level == 1) { if (level1(password)) { printf("Password passed check 1.\n"); } else { printf("Password did not pass check 1.\n"); } } else if (level == 2) { if (level2(password, param)) { printf("Password did pass the check.\n"); } else { printf("Password did not pass the check.\n"); } } // Add level3 and level4 logic here later return 0; }
Key Improvements
- No more global variables: All values are passed as arguments or stored locally, so there's no cross-function value pollution.
- Single input read: The password is read once in
mainand reused across all validation functions. - Cleaner logic: A helper function eliminates repeated counting code, and
switchmakes thelevel2param handling easier to read. - Better error handling: Argument validation happens upfront, with clear error messages.
内容的提问来源于stack exchange,提问作者Jan Kvapil

