Pascal日期验证程序EConvertError异常问题求助
解决你的Pascal日期验证程序崩溃问题
你的问题很清晰:连续两次输入回车(空字符串)后程序崩溃,报错EConvertError:""是无效整数,这确实是空字符串被传入StrToInt函数导致的异常。咱们一步步拆解原因和修复方案:
崩溃的核心原因
当你输入空字符串时,程序没有提前拦截这个无效输入,直接尝试处理空内容:
- 第一次回车:进入
DateVerification函数后,首先触发len <> 8的判断(空字符串长度为0),程序弹出错误提示后返回false,errorCatch被设为true,循环回到输入步骤。此时还没走到StrToInt的调用,所以没崩溃。 - 第二次回车:同样进入
DateVerification,但主程序里在验证失败后依然执行了year := ((StrToInt(userInputArray[6]))*10) + StrToInt(userInputArray[7]);这行代码。此时userInput是空字符串,userInputArray[6]和userInputArray[7]都是空字符串,调用StrToInt("")直接抛出未处理的转换异常,导致程序崩溃。
另外,DateVerification函数本身也有隐患:如果输入长度不足8(比如空字符串),后续访问userInputArray[6]、userInputArray[3]等位置时,数组元素是空字符串,一旦走到StrToInt调用也会崩溃,只是第一次回车时提前触发了长度判断,没走到那一步而已。
具体修复步骤
1. 先拦截空输入
在主程序读取输入后,第一时间检查是否为空,直接提示错误并重新循环:
ReadLn(userInput); // 新增:拦截空输入 if userInput = '' then begin ClrScr(); TextColor(Red); WriteLn('输入不能为空,请重新输入!'); TextColor(White); Readkey(); ClrScr(); errorCatch := true; continue; // 跳过后续代码,直接回到循环开头 end;
2. 修复DateVerification函数的逻辑漏洞
在函数开头先检查输入是否为空,并且确保所有StrToInt调用都在输入有效的前提下执行:
function DateVerification(var userInput: string): boolean; var errorLimit : boolean; bounds: integer; begin errorLimit := True; DateVerification := False; // 默认返回false,直到所有验证通过 // 新增:先检查空输入 if userInput = '' then begin ClrScr(); TextColor(Red); WriteLn('输入不能为空,请重新输入!'); TextColor(White); Readkey(); ClrScr(); errorLimit := false; Exit; end; len := Length(userInput); if (len <> 8) and (errorLimit = True) then begin ClrScr(); TextColor(Red); WriteLn('input was not the right length (8 characters)'); TextColor(White); Write('make sure date fits format '); TextColor(LightGreen); WriteLn('dd/mm/yy'); TextColor(White); Readkey(); ClrScr(); errorLimit := false; Exit; end; // 分割字符到数组 for i := 1 to len do userInputArray[i - 1] := userInput[i]; // 检查斜杠位置 if (userInputArray[2] <> '/') or (userInputArray[5] <> '/') and (errorLimit = true) then begin ClrScr(); TextColor(Red); WriteLn('input did not have slashes in correct locations '); TextColor(LightGreen); WriteLn('dd/mm/yy'); TextColor(White); Readkey(); ClrScr(); errorLimit := false; Exit; end; // 所有StrToInt调用都在errorLimit为true的前提下执行 if errorLimit then begin year := ((StrToInt(userInputArray[6]))*10) + StrToInt(userInputArray[7]); if (year < 0) or (year > 99) then // 修正:yy格式应该是0-99,原代码写的1-99 begin ClrScr(); TextColor(Red); WriteLn('year was not from 0 to 99'); TextColor(White); Readkey(); ClrScr(); errorLimit := false; Exit; end; month := ((StrToInt(userInputArray[3]))*10) + StrToInt(userInputArray[4]); if (month < 1) or (month > 12) then begin ClrScr(); TextColor(Red); WriteLn('month was not from 1 to 12'); TextColor(White); Readkey(); ClrScr(); errorLimit := false; Exit; end; day := ((StrToInt(userInputArray[0]))*10) + StrToInt(userInputArray[1]); // 月份天数判断 if (month = 4) or (month = 6) or (month = 9) or (month = 11) then bounds := 30 else if (month = 2) then begin if IsLeapYear(year) then bounds := 29 else bounds := 28; end else bounds := 31; if (day < 1) or (day > bounds) then begin ClrScr(); TextColor(Red); WriteLn('day was not from 1 to days in month'); TextColor(White); Readkey(); ClrScr(); errorLimit := false; Exit; end; end; if errorLimit then DateVerification := True; end;
3. 移除主程序中多余的StrToInt调用
主程序里在DateVerification之后的那几行StrToInt代码是多余的,而且是第二次崩溃的直接原因,直接删掉:
// 删掉以下代码块 len := Length(userInput); for i := 1 to len do userInputArray[i - 1] := userInput[i]; year := ((StrToInt(userInputArray[6]))*10) + StrToInt(userInputArray[7]);
4. 修复IsLeapYear函数的逻辑
你的IsLeapYear参数是yy格式的年份(0-99),但实际要判断的是2000-2099的完整年份,需要转换为完整年份后再判断,否则像00(2000年)这样的年份会判断错误:
function IsLeapYear(year: integer): boolean; // 不需要var参数,因为不修改原变量 var fullYear: integer; begin fullYear := 2000 + year; if (fullYear mod 4 = 0) then begin if (fullYear mod 100 = 0) then IsLeapYear := (fullYear mod 400 = 0) else IsLeapYear := true; end else IsLeapYear := false; end;
额外的小建议
- 尽量避免使用全局变量(比如
userInputArray、len、year等),可以把它们放到函数内部,减少变量冲突的风险。 - 可以用
TryStrToInt替代StrToInt来安全转换,避免抛出异常,比如:var digit: integer; if not TryStrToInt(userInputArray[6], digit) then begin ClrScr(); TextColor(Red); WriteLn('年份输入不是有效数字!'); TextColor(White); Readkey(); ClrScr(); errorLimit := false; Exit; end;
这样可以处理用户输入非数字字符的情况,让程序更健壮。
内容的提问来源于stack exchange,提问作者Chibi Ayano
相关产品推荐
相关产品推荐

