You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

4×4键盘密码读取有限状态机故障:需按5次按键才进CHECK状态

Fixing the Extra Keypress Issue in Your 4x4 Keypad State Machine

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

  1. Missing state update in the FOURTH case: You probably aren't setting password = CHECK immediately 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.
  2. Out-of-sync i counter: Your i variable might not be aligned with the state (e.g., you increment i but don't switch state, or vice versa), making the 4th keypress fail the condition in the FOURTH case and fall to default.
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:46:27