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

Arduino C++字符串比较问题:密码验证功能实现故障排查

Arduino密码验证问题:密码匹配失败的原因与修复方案

核心问题:局部数组指针的非法访问

你的Input函数里定义了char output[Length];,这是栈上的局部变量,函数执行完毕后,这块内存会被系统回收。你返回这个数组的指针,拿到的是指向无效内存的野指针,后续用它赋值给String test或用strcmp比较,结果都是不可预测的——这就是密码匹配失败的根本原因。

修复方案:两种正确的实现方式

方式1:使用Arduino的String类(贴近Java使用习惯)

直接让Input函数返回String类型,避免指针问题,比较时直接用==即可:

String pswd = "0000";

String Input(int Length, byte clmn, byte row) { 
    String output = "";
    int i = 0;
    while (i < Length) {
        char KeyPress = keypad.getKey();
        lcd.setCursor(clmn, row);
        // 简化数字判断逻辑
        if (KeyPress >= '0' && KeyPress <= '9') {
            output += KeyPress;
            lcd.print(KeyPress);
            i++;
            clmn++; 
            lcd.setCursor(i + 1, 0);
            lcd.cursor();
        }
    }
    delay(3000);
    Serial.println(output);
    return output;
}

bool Is_Psswrd() { 
    bool Passed = false;
    bool CH2 = true;
  
    while (CH2) {   
        say("Password: ", 0, 0);
        String test = Input(4, 10, 0);
        if (test == pswd) {
            Passed = true;
            CH2 = false;
        } else {
            lcd.clear();
            say("Incorrect ", 0, 0);
            delay(600);
        } 
    }
    return Passed;
}   

void setup() {
  // 补充LCD和键盘的初始化代码
  lcd.begin(16, 2);
  // keypad.begin(); // 根据你的键盘库补充初始化
  Is_Psswrd();
}

void loop() {}

方式2:使用C风格char数组(避免String的内存碎片化)

如果想用strcmp比较,需确保两个char数组有效且以\0结尾(C风格字符串的标志)。可以通过传入数组到Input函数填充,而非返回局部数组指针:

const char* pswd = "0000"; // 用const char*存储固定密码

void Input(char* output, int Length, byte clmn, byte row) { 
    int i = 0;
    memset(output, 0, Length + 1); // 清空数组,确保末尾有终止符\0
    while (i < Length) {
        char KeyPress = keypad.getKey();
        lcd.setCursor(clmn, row);
        if (KeyPress >= '0' && KeyPress <= '9') {
            output[i] = KeyPress;
            lcd.print(KeyPress);
            i++;
            clmn++; 
            lcd.setCursor(i + 1, 0);
            lcd.cursor();
        }
    }
    delay(3000);
    Serial.println(output);
}

bool Is_Psswrd() { 
    bool Passed = false;
    bool CH2 = true;
    char test[5]; // 4位密码+1位终止符\0,总长度为5
  
    while (CH2) {   
        say("Password: ", 0, 0);
        Input(test, 4, 10, 0);
        // strcmp返回0表示两个字符串内容完全相等
        if (strcmp(test, pswd) == 0) {
            Passed = true;
            CH2 = false;
        } else {
            lcd.clear();
            say("Incorrect ", 0, 0);
            delay(600);
        } 
    }
    return Passed;
}   

void setup() {
  lcd.begin(16, 2);
  // keypad.begin(); // 补充键盘初始化代码
  Is_Psswrd();
}

void loop() {}

关键知识点说明

  1. 局部变量内存生命周期:栈上的局部变量在函数结束后会被销毁,返回其指针会产生野指针——这是C和Java的核心区别之一(Java有垃圾回收,C需手动管理内存)。
  2. 字符串对比规则:
    • Arduino的String类支持直接用==对比,内部已实现内容匹配逻辑。
    • C风格char*必须用strcmp函数,返回0才表示内容完全相同;你之前得到144的结果,本质是野指针指向的无效内存导致对比失效。

内容的提问来源于stack exchange,提问作者Ian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:10:34