4×4键盘密码读取有限状态机故障:需按5次按键才进CHECK状态
Got it, let's figure out why you're stuck needing a 5th keypress to trigger the CHECK state instead of the 4th. This is almost certainly a state transition timing or synchronization problem between your password state variable, the i counter, and how you handle the FOURTH state. Let's break this down:
Likely Root Causes
- Missing state update in the FOURTH case: You probably aren't setting
password = CHECKimmediately after validating the 4th correct keypress. Instead, the state stays on FOURTH, so the next keypress hits the default branch before finally switching to CHECK. - Out-of-sync
icounter: Yourivariable might not be aligned with the state (e.g., you incrementibut don't switch state, or vice versa), making the 4th keypress fail the condition in the FOURTH case and fall to default. - Default branch logic overriding state: If your default branch has code that switches to CHECK only after an extra keypress, that's forcing the 5th input.
Step-by-Step Fixes
1. Ensure Immediate State Transition in FOURTH
The key fix is updating the state to CHECK right after validating the 4th correct key. Here's how to adjust your FOURTH case:
case FOURTH: // Assuming your 4th correct key is, say, 2, and i should be 3 (0-indexed) if (key == 2 && i == 3) { temp++; i++; password = CHECK; // Critical: Switch state NOW, not later // Optional: You can even run your CHECK logic here immediately if needed } else { // Handle wrong input: reset state/counter temp = 0; i = 0; password = FIRST; } break;
This ensures the 4th keypress triggers the state switch to CHECK immediately, so the next loop iteration will hit the CHECK case instead of waiting for another key.
2. Sync i Counter with State Transitions
Double-check that i increments exactly when you switch states, so they stay aligned:
- FIRST state (i=0) → correct key → i=1 → switch to SECOND
- SECOND state (i=1) → correct key → i=2 → switch to THIRD
- THIRD state (i=2) → correct key → i=3 → switch to FOURTH
- FOURTH state (i=3) → correct key → i=4 → switch to CHECK
If i gets out of sync (e.g., you increment it twice, or not at all), the condition in the FOURTH case will fail, sending you to the default branch.
3. Debug with Print Statements
Add quick debug prints to track state, i, and temp after each keypress—this will show you exactly what's happening:
// After handling each key press printf("State: %d | i: %d | temp: %d\n", password, i, temp);
For the 4th correct keypress, you should see the state switch directly to CHECK. If it stays on FOURTH, you know your state update line is missing or not triggering.
4. Check get_key() for Duplicate Reads
Make sure your get_key() function isn't reading the same keypress twice (e.g., not waiting for the key to be released). If it's returning the same key twice, that could make it seem like you need an extra press—add a debounce or key-release check if needed.
Example Working Snippet
Here's a trimmed-down version of how your state machine should flow for a 4-digit password:
typedef enum { FIRST, SECOND, THIRD, FOURTH, CHECK, ERROR } PasswordState; PasswordState password = FIRST; int i = 0; int temp = 0; const int correct_pass[] = {7, 1, 4, 2}; // Example password while (1) { int key = get_key(); if (key >= 0 && key <= 9) { switch (password) { case FIRST: if (key == correct_pass[0] && i == 0) { temp++; i++; password = SECOND; } else { temp=0; i=0; password=FIRST; } break; case SECOND: if (key == correct_pass[1] && i == 1) { temp++; i++; password = THIRD; } else { temp=0; i=0; password=FIRST; } break; case THIRD: if (key == correct_pass[2] && i == 2) { temp++; i++; password = FOURTH; } else { temp=0; i=0; password=FIRST; } break; case FOURTH: if (key == correct_pass[3] && i == 3) { temp++; i++; password = CHECK; // Immediate state switch } else { temp=0; i=0; password=FIRST; } break; case CHECK: // Run your validation logic here if (temp == 4) printf("Password Accepted!\n"); else printf("Password Failed!\n"); // Reset for next input temp=0; i=0; password=FIRST; break; default: // Handle unexpected state: reset temp=0; i=0; password=FIRST; break; } } }
With this setup, the 4th correct keypress will immediately switch to the CHECK state, no extra input required.
内容的提问来源于stack exchange,提问作者hello you

