Pascal代码遍历用户名文本文件仅读取3行就停止问题排查
问题原因
你的程序提前终止的核心原因是行解析逻辑未处理无分隔符的异常场景,其次还有多处逻辑缺陷会触发运行时错误:
- 当读取到的行不存在
#分隔符时,Pos('#', sline)会返回0,此时计算得到的iPos - 1 = -1,Pascal的Copy函数传入负长度参数时,如果开启了编译器范围检查选项,会直接触发运行时错误,导致程序崩溃终止,这就是你仅能读取3行就停止的直接诱因(大概率第4行存在格式问题、或者是之前写入不规范导致的空行/无分隔符行)。 - 你写入新用户时仅使用
#13(回车符)作为换行,Windows系统标准换行符是#13#10,会导致后续读取时将多行识别为同一行,进一步触发分隔符解析错误。 - 用户名匹配逻辑大小写敏感,会出现
alex和Alex被判定为不同用户的问题,不符合普通业务需求。 - 匹配到重复用户名后未跳出循环,会无意义遍历剩余行,影响性能。
修复方案
可以参考以下调整后的代码:
var sFileChar: Char; iPos: Integer; bFlag: Boolean; sline: string; begin bFlag := False; // 先校验用户名非空 if Trim(sUsername) = '' then Exit; sFileChar := UpCase(sUsername[1]); AssignFile(tfile, sFileChar + '.txt'); // 增加文件不存在的兼容逻辑 if not FileExists(sFileChar + '.txt') then begin Rewrite(tfile); CloseFile(tfile); end; Reset(tfile); try while not Eof(tfile) do begin Readln(tfile, sline); iPos := Pos('#', sline); // 跳过格式错误的行,不终止程序 if (iPos = 0) or (Trim(sline) = '') then Continue; // 大小写不敏感匹配 if SameText(sUsername, Copy(sline, 1, iPos - 1)) then begin bFlag := True; // 找到匹配直接跳出循环 Break; end; end; if bFlag then begin ShowMessage('That username is already taken'); end else begin Append(tfile); // 写入标准换行符 Writeln(tfile, sUsername + '#' + sPassword + '#' + rgpUserType.Items[rgpUserType.ItemIndex]); end; finally // 统一在finally块关闭文件,确保异常时也能释放句柄 CloseFile(tfile); end; end;
内容的提问来源于stack exchange,提问作者MelkorIlluvatar
相关产品推荐
相关产品推荐

