Program Throwing Unknown Error: EConvertError
Program Throwing Unknown Error: EConvertError
我正在尝试创建一个接受用户输入并检查其是否有效的日期(2000 - 2099 年)的程序。当我对我连续两次输入 enter 作为输入的代码进行 bug 测试时,我第一次输入 enter 时没有抛出任何错误,但第二次控制台闪烁一条消息并崩溃。我在它崩溃时拍了一张截图,这是它显示的错误
An unhandled exception occured at [=10=]40CDE1
EConvertError : "" is an invalid integer
我最好的猜测是错误是由我的 StrToInt
之一引起的 EConvertError
但我不清楚为什么它只在第二个 运行 通过而不是第一。我怀疑错误发生在任何一行,85、98、111 或 195。
当我最初编写这个程序时,我是 Pascal 的初学者,所以对于任何草率的代码,我提前表示歉意。
下面是所有代码,如果您想 运行 自己使用的话。
program DateVerifierAssignment;
uses crt, sysutils;
var
userInputArray: array[0..7] of string;
len, i, day, month, year: integer;
date, userInput, stringDay, stringMonth, stringYear: string;
errorCatch: boolean;
//DECLARING FUNCTIONS & PROCEDURES
procedure TitleScreen();
begin
//prints a coloured wall of text to give information like name and instructions
WriteLn(' o-------------------------o');
Write(' | ');TextColor(White);Write('Date Validation Program');TextColor(Cyan);WriteLn(' |');
WriteLn(' o-------------------------o');
WriteLn();
WriteLn(' o-------------------------o');
Write(' | ');TextColor(White);Write('Instructions');TextColor(Cyan);WriteLn(' |');
WriteLn(' o-------------------------o');
Write(' | ');TextColor(White);Write('Enter a date and the');TextColor(Cyan);WriteLn(' |');
Write(' | ');TextColor(White);Write('program will verify it');TextColor(Cyan);WriteLn(' |');
Write(' | ');TextColor(White);Write('and convert it to its');TextColor(Cyan);WriteLn(' |');
Write(' | ');TextColor(White);Write('long form');TextColor(Cyan);WriteLn(' |');
WriteLn(' o-------------------------o');
WriteLn();
TextColor(White);
Write(' press any key to begin');
//waits for user input then clears the screen and returns the text color to white
ReadKey();
ClrScr;
end;
function DateVerification(var userInput: string): boolean;
var
errorLimit : boolean;
bounds: integer;
begin
errorLimit := True;
//stores the length of the string as a variable
len := Length(userInput);
//checks to see if entry is 8 chracters long and displays an error message and returns user to input screen if it doesn't fit
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;
Dateverification := false;
end;
//spits each character into its own spot in an array
for i := 1 to len do
userInputArray[i - 1] := userInput[i];
//tests if every slot in the array where a slash should be is a slash
for i := 0 to len-1 do
begin
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;
Dateverification := false;
end;
end;
year := ((StrToInt(userInputArray[6]))*10) + StrToInt(userInputArray[7]);
if (year < 1) or (year > 99) and (errorLimit = true) then
begin
ClrScr();
TextColor(Red);
WriteLn('year was not from 0 to 99');
TextColor(White);
Readkey();
ClrScr();
errorLimit := false;
Dateverification := false;
end;
month := ((StrToInt(userInputArray[3]))*10) + StrToInt(userInputArray[4]);
if (month < 1) or (month > 12) and (errorLimit = true) then
begin
ClrScr();
TextColor(Red);
WriteLn('month was not from 1 to 12');
TextColor(White);
Readkey();
ClrScr();
errorLimit := false;
Dateverification := false;
end;
day := ((StrToInt(userInputArray[0]))*10) + StrToInt(userInputArray[1]);
if (month = 4) or (month = 6) or (month = 9) or (month = 11) then
bounds := 30;
if (month = 2) then
begin
if (IsLeapYear(year) = true) then
bounds := 29
else
bounds := 28;
end
else
bounds := 31;
if (day < 1) or (day > bounds) and (errorLimit = true) then
begin
ClrScr();
TextColor(Red);
WriteLn('day was not from 1 to days in month');
TextColor(White);
Readkey();
ClrScr();
errorLimit := false;
Dateverification := false;
end;
if (errorLimit = true) then
DateVerification := True;
end;
function IsLeapYear(var year: integer): boolean;
//simple function to determine if a year is a leap year on the gregorian calender
begin
if (year mod 4) = 0 then
if (year mod 100 <> 0) then
if (year mod 400 = 0) then
IsLeapYear := true
else
IsLeapYear := false
else
IsLeapyear := false
else
IsLeapyear := false
end;
procedure DateToAlpha(var userInput: string);
begin
end;
//MAIN PROGRAM
begin
//preparing for while loop later in code and changes text colour to cyan
errorCatch := true;
TextColor(Cyan);
//Displays a title screen and instruction about how to use(stored in a procedure to help with readability)
TitleScreen();
//begins a loop so that if an error is to occur the program can easily ask for a new date and try again
while (errorCatch = true) do
begin
//sets error catch to 0 so that if there a no errors the program will not loop
errorCatch := false;
//displays information on how to input a date as well as an example with different colours for better readability
Write('Enter a date in the format');TextColor(LightGreen); WriteLn(' dd/mm/yy');TextColor(White);
Write('e.g. ');TextColor(LightGreen);WriteLn(' 09/07/20'#13#10);TextColor(White);
//takes date user inputs and stores it
ReadLn(userInput);
//calls the date verification function to see if the date is valid
//(refer to dateVerification at the top of the program for more info and comments)
if (DateVerification(userInput) = false) then
errorCatch := true;
len := Length(userInput);
for i := 1 to len do
userInputArray[i - 1] := userInput[i];
year := ((StrToInt(userInputArray[6]))*10) + StrToInt(userInputArray[7]);
readKey();
end;
end.
通常在 SO 上我们不提供 fully-coded 显然是课程作业的问题答案。
在这种情况下,我想我会例外,因为很明显你在做
不必要的恶劣天气,以及您对其进行编码的方式可能实际上会妨碍
调试它并使其正常工作。
所以,下面的例子展示了一个非常简单的,
验证以 dd/mm/yyyy 格式提供的 21 世纪日期的简洁方法。它
显示处理和验证步骤的正确顺序;如果检测到错误
在任何一步,它都会说出问题所在并停止。如果执行下降到最后,
提供的日期字符串必须有效。
我故意遗漏了任何循环
或美化代码,因为重要的是首先是一个干净简洁的
处理和验证步骤的编码。如果你想使用循环,很好,但是你使用的方式
例如errorCatch,我敢打赌,如果你在 6 个月后回来查看你的代码,你将不记得如何
它应该工作。对于此任务,您不需要任何复杂的标志或循环 - 用户只需能够恰好键入八个字符(后跟 [Enter]),然后代码会告诉它是否有效。
请注意,我使用标准的复制功能将文件的各个部分分开
输入的日期。顺便说一句,你的声明
userInputArray: array[0..7] of string;
完全错误。如果你想要一个包含一定数量 个字符 的数组,没问题,但那会
只是不必要地使处理和处理用户输入的内容复杂化。很远
更简单,因此接受 8 个字符的单个 string 的 error-prone 更少
并处理它。但在任何情况下,要允许字符串在日期和月份数字后包含 /
个字符,stringg 的长度应为 10,而不是八,以允许这些数字和四年数字。
program DateVerification;
uses
SysUtils;
var
sUserInput,
sDay,
sMonth,
sYear : String;
iDay,
iMonth,
iYear,
iDays: Integer;
bIsLeapYear : Boolean;
function DaysInMonth(iMonth, iYear : Integer) : Integer;
begin
Result := -1; // you supply the code for this taking into account leap year for February
end;
begin
writeln('Please enter a date between 01/01/2000 and 31/12/2099 in the format shown');
readln(sUserInput);
if Length(sUserInput) <> 10 then begin
writeln('Input is wrong length.');
Halt;
end;
if (sUserInput[3] <> '/') or (sUserInput[6] <> '/') then begin
writeln('Input is incorrectly delimited.');
Halt;
end;
sDay := Copy(sUserInput, 1, 2);
sMonth := Copy(sUserInput, 4, 2);
sYear := Copy(sUserInput, 7, 4);
iYear := StrToInt(sYear);
if (iYear < 2000) or (iYear > 2099) then begin
writeln('Invalid year : ', sYear);
Halt;
end;
bIsLeapYear := IsLeapYear(iYear); // you supply the code for IsLeapYear
iMonth := StrToInt(sMonth);
if (iMonth < 1) or (iMonth > 12) then begin
writeln('Invalid month : ', sMonth);
Halt;
end;
iDay := StrToInt(sDay);
if (iDay < 1) or (iDay > DaysInMonth(iMonth, iYear)) then begin
// You need to supply the DaysInMoth function, which of course
// needs to account for February in a leap year
writeln('Invalid day of month: ', sMonth);
Halt;
end;
writeln(sUserInput, ' is a valid date.');
readln;
end.
我正在尝试创建一个接受用户输入并检查其是否有效的日期(2000 - 2099 年)的程序。当我对我连续两次输入 enter 作为输入的代码进行 bug 测试时,我第一次输入 enter 时没有抛出任何错误,但第二次控制台闪烁一条消息并崩溃。我在它崩溃时拍了一张截图,这是它显示的错误
An unhandled exception occured at [=10=]40CDE1
EConvertError : "" is an invalid integer
我最好的猜测是错误是由我的 StrToInt
之一引起的 EConvertError
但我不清楚为什么它只在第二个 运行 通过而不是第一。我怀疑错误发生在任何一行,85、98、111 或 195。
当我最初编写这个程序时,我是 Pascal 的初学者,所以对于任何草率的代码,我提前表示歉意。
下面是所有代码,如果您想 运行 自己使用的话。
program DateVerifierAssignment;
uses crt, sysutils;
var
userInputArray: array[0..7] of string;
len, i, day, month, year: integer;
date, userInput, stringDay, stringMonth, stringYear: string;
errorCatch: boolean;
//DECLARING FUNCTIONS & PROCEDURES
procedure TitleScreen();
begin
//prints a coloured wall of text to give information like name and instructions
WriteLn(' o-------------------------o');
Write(' | ');TextColor(White);Write('Date Validation Program');TextColor(Cyan);WriteLn(' |');
WriteLn(' o-------------------------o');
WriteLn();
WriteLn(' o-------------------------o');
Write(' | ');TextColor(White);Write('Instructions');TextColor(Cyan);WriteLn(' |');
WriteLn(' o-------------------------o');
Write(' | ');TextColor(White);Write('Enter a date and the');TextColor(Cyan);WriteLn(' |');
Write(' | ');TextColor(White);Write('program will verify it');TextColor(Cyan);WriteLn(' |');
Write(' | ');TextColor(White);Write('and convert it to its');TextColor(Cyan);WriteLn(' |');
Write(' | ');TextColor(White);Write('long form');TextColor(Cyan);WriteLn(' |');
WriteLn(' o-------------------------o');
WriteLn();
TextColor(White);
Write(' press any key to begin');
//waits for user input then clears the screen and returns the text color to white
ReadKey();
ClrScr;
end;
function DateVerification(var userInput: string): boolean;
var
errorLimit : boolean;
bounds: integer;
begin
errorLimit := True;
//stores the length of the string as a variable
len := Length(userInput);
//checks to see if entry is 8 chracters long and displays an error message and returns user to input screen if it doesn't fit
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;
Dateverification := false;
end;
//spits each character into its own spot in an array
for i := 1 to len do
userInputArray[i - 1] := userInput[i];
//tests if every slot in the array where a slash should be is a slash
for i := 0 to len-1 do
begin
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;
Dateverification := false;
end;
end;
year := ((StrToInt(userInputArray[6]))*10) + StrToInt(userInputArray[7]);
if (year < 1) or (year > 99) and (errorLimit = true) then
begin
ClrScr();
TextColor(Red);
WriteLn('year was not from 0 to 99');
TextColor(White);
Readkey();
ClrScr();
errorLimit := false;
Dateverification := false;
end;
month := ((StrToInt(userInputArray[3]))*10) + StrToInt(userInputArray[4]);
if (month < 1) or (month > 12) and (errorLimit = true) then
begin
ClrScr();
TextColor(Red);
WriteLn('month was not from 1 to 12');
TextColor(White);
Readkey();
ClrScr();
errorLimit := false;
Dateverification := false;
end;
day := ((StrToInt(userInputArray[0]))*10) + StrToInt(userInputArray[1]);
if (month = 4) or (month = 6) or (month = 9) or (month = 11) then
bounds := 30;
if (month = 2) then
begin
if (IsLeapYear(year) = true) then
bounds := 29
else
bounds := 28;
end
else
bounds := 31;
if (day < 1) or (day > bounds) and (errorLimit = true) then
begin
ClrScr();
TextColor(Red);
WriteLn('day was not from 1 to days in month');
TextColor(White);
Readkey();
ClrScr();
errorLimit := false;
Dateverification := false;
end;
if (errorLimit = true) then
DateVerification := True;
end;
function IsLeapYear(var year: integer): boolean;
//simple function to determine if a year is a leap year on the gregorian calender
begin
if (year mod 4) = 0 then
if (year mod 100 <> 0) then
if (year mod 400 = 0) then
IsLeapYear := true
else
IsLeapYear := false
else
IsLeapyear := false
else
IsLeapyear := false
end;
procedure DateToAlpha(var userInput: string);
begin
end;
//MAIN PROGRAM
begin
//preparing for while loop later in code and changes text colour to cyan
errorCatch := true;
TextColor(Cyan);
//Displays a title screen and instruction about how to use(stored in a procedure to help with readability)
TitleScreen();
//begins a loop so that if an error is to occur the program can easily ask for a new date and try again
while (errorCatch = true) do
begin
//sets error catch to 0 so that if there a no errors the program will not loop
errorCatch := false;
//displays information on how to input a date as well as an example with different colours for better readability
Write('Enter a date in the format');TextColor(LightGreen); WriteLn(' dd/mm/yy');TextColor(White);
Write('e.g. ');TextColor(LightGreen);WriteLn(' 09/07/20'#13#10);TextColor(White);
//takes date user inputs and stores it
ReadLn(userInput);
//calls the date verification function to see if the date is valid
//(refer to dateVerification at the top of the program for more info and comments)
if (DateVerification(userInput) = false) then
errorCatch := true;
len := Length(userInput);
for i := 1 to len do
userInputArray[i - 1] := userInput[i];
year := ((StrToInt(userInputArray[6]))*10) + StrToInt(userInputArray[7]);
readKey();
end;
end.
通常在 SO 上我们不提供 fully-coded 显然是课程作业的问题答案。
在这种情况下,我想我会例外,因为很明显你在做 不必要的恶劣天气,以及您对其进行编码的方式可能实际上会妨碍 调试它并使其正常工作。
所以,下面的例子展示了一个非常简单的, 验证以 dd/mm/yyyy 格式提供的 21 世纪日期的简洁方法。它 显示处理和验证步骤的正确顺序;如果检测到错误 在任何一步,它都会说出问题所在并停止。如果执行下降到最后, 提供的日期字符串必须有效。
我故意遗漏了任何循环 或美化代码,因为重要的是首先是一个干净简洁的 处理和验证步骤的编码。如果你想使用循环,很好,但是你使用的方式 例如errorCatch,我敢打赌,如果你在 6 个月后回来查看你的代码,你将不记得如何 它应该工作。对于此任务,您不需要任何复杂的标志或循环 - 用户只需能够恰好键入八个字符(后跟 [Enter]),然后代码会告诉它是否有效。
请注意,我使用标准的复制功能将文件的各个部分分开 输入的日期。顺便说一句,你的声明
userInputArray: array[0..7] of string;
完全错误。如果你想要一个包含一定数量 个字符 的数组,没问题,但那会
只是不必要地使处理和处理用户输入的内容复杂化。很远
更简单,因此接受 8 个字符的单个 string 的 error-prone 更少
并处理它。但在任何情况下,要允许字符串在日期和月份数字后包含 /
个字符,stringg 的长度应为 10,而不是八,以允许这些数字和四年数字。
program DateVerification;
uses
SysUtils;
var
sUserInput,
sDay,
sMonth,
sYear : String;
iDay,
iMonth,
iYear,
iDays: Integer;
bIsLeapYear : Boolean;
function DaysInMonth(iMonth, iYear : Integer) : Integer;
begin
Result := -1; // you supply the code for this taking into account leap year for February
end;
begin
writeln('Please enter a date between 01/01/2000 and 31/12/2099 in the format shown');
readln(sUserInput);
if Length(sUserInput) <> 10 then begin
writeln('Input is wrong length.');
Halt;
end;
if (sUserInput[3] <> '/') or (sUserInput[6] <> '/') then begin
writeln('Input is incorrectly delimited.');
Halt;
end;
sDay := Copy(sUserInput, 1, 2);
sMonth := Copy(sUserInput, 4, 2);
sYear := Copy(sUserInput, 7, 4);
iYear := StrToInt(sYear);
if (iYear < 2000) or (iYear > 2099) then begin
writeln('Invalid year : ', sYear);
Halt;
end;
bIsLeapYear := IsLeapYear(iYear); // you supply the code for IsLeapYear
iMonth := StrToInt(sMonth);
if (iMonth < 1) or (iMonth > 12) then begin
writeln('Invalid month : ', sMonth);
Halt;
end;
iDay := StrToInt(sDay);
if (iDay < 1) or (iDay > DaysInMonth(iMonth, iYear)) then begin
// You need to supply the DaysInMoth function, which of course
// needs to account for February in a leap year
writeln('Invalid day of month: ', sMonth);
Halt;
end;
writeln(sUserInput, ' is a valid date.');
readln;
end.