Board logo

标题: [讨论]批处理怎样判断用户输入(日期)的正确性+合法性 [打印本页]

作者: maxil    时间: 2010-1-9 14:14     标题: [讨论]批处理怎样判断用户输入(日期)的正确性+合法性

写了一个批处理,功能为:从一个文件读出用户输入的生日,然后判断出他现在多少岁。
如果只就这个问题本生而言,实现起来是很简单的。但!!!

问题来了:如何判断用户输入格式的正确性以及合法性呢

比如当输入为    2010 4 5、2009.1202、1985.01.02 等等时, 我们应该怎样判断处理?
还有如果输入是    2010.15.33  呢?
再比如遇到     1997.2.29  这样的日期,又该怎样更好的对待?
或者再多点,农历怎么办?


我的一些想法:
(1)关于输入的正确性,我们可以在他输入之前,做一些要求,比如要求输入格式为
         年.月.日    如:1985.1.12  
         当然,虽然限制了,但如果别人输入的还是不合要求,那我们的程序也不能出错吧!
         如果输入是 1985.01.02  该怎么弄呢?月和日前面是否有0还要需要区分啊!

         (刚刚发现读入用户输入时用 SET /a 可以吧01 转化为1)

(2)关于合法性,我们可以把输入的日期和正常的比较,比如当月大于12 就提示出错,但
         我们做的只是个小程序的话,貌似这些代码就比实现代码都多了,⊙﹏⊙b汗
         怎样才能简洁而更好的判断处理呢?

希望大家都可以说说自己的想法,看看都有什么好的方法~

以下是我的小程序(貌似是过于复杂了,汗!水平问题。不是本贴的主要内容)
  1. @ECHO off&SETLOCAL EnableDelayedExpansion
  2. TITLE 计算年龄
  3. :START
  4. SET birth=%temp%\age.txt
  5. ECHO ;请在下一行请输入你的生日,例如 1988.2.14 输入完成后保存并关闭>%birth%
  6. START /wait %birth%
  7. FOR /f "eol=; tokens=1-3 delims=." %%i in (%birth%) do SET /a year_b=%%i,month_b=%%j,day_b=%%k
  8. SET /a year_n=%date:~,4%,month_n=1%date:~5,2%%%100,day_n=1%date:~8,2%%%100
  9. SET flag=
  10. FOR %%a in (year month day) do if "!%%a_b!" equ "" set "flag=a"
  11. IF defined flag CLS&ECHO 你输入的生日有误。请按照提示格式重新输入!&CALL :START
  12. ECHO 你输入的年龄是 %year_b%年%month_b%月%day_b%日
  13. Set /a age=%year_n%-%year_b%
  14. If %month_n% gtr %month_b% CALL :age
  15. If %month_n% lss %month_b% CALL :less_age
  16. If %month_n% equ %month_b% (
  17.                      If %day_n:~0,2% gtr %day_b% call :age
  18.                      If %day_n:~0,2% equ %day_b% (call :age
  19.                              ECHO 哈哈 ,今天是你的生日啊!
  20.                                     )
  21.                      If %day_n:~0,2% lss %day_b% call :less_age
  22. )
  23. PAUSE>nul&EXIT
  24. :age
  25. ECHO 你现在的年龄是:%age% 岁!
  26. GOTO :eof
  27. :less_age
  28. SET /a age=%age%-1
  29. ECHO 你现在的年龄是:%age% 岁!
  30. GOTO :eof
复制代码


[ 本帖最后由 maxil 于 2010-1-9 16:14 编辑 ]
作者: 随风    时间: 2010-1-9 14:37

首先你应该给出什么是合法的日期格式
比如:2009 12 08 和 2009 12 8 这样都是合法的吗?
格式必须是 年 月 日 吗?
年月日之间允许用那些符号来格开?
年必须是4位数吗?
月必须是2位数吗?
日必须是2位数吗?
作者: vsbat    时间: 2010-1-9 14:47

我感觉你不应该去满足用户的所有可能格式---
比如农历什么的,应该有个输入提示,告诉用户诸如什么样的是合法格式,下面你要作的就是判断输入的是否合乎你的定义

把规范的都 定义成变量
如果输入的 if not defined  就是不和法的

不知下面这个 帖子是否有帮助:

http://bathome.l3.wuyou.com/viewthread.php?tid=6638&page=1#pid43043
作者: maxil    时间: 2010-1-9 14:49

原帖由 随风 于 2010-1-9 14:37 发表
首先你应该给出什么是合法的日期格式
比如:2009 12 08 和 2009 12 8 这样都是合法的吗?
格式必须是 年 月 日 吗?
年月日之间允许用那些符号来格开?
年必须是4位数吗?
月必须是2位数吗?
日必须是2位数吗? ...


恩 我发出来讨论的目的也就是这个,在程序里我给的示例是1988.2.14 ,也就是说年月日要用 . 隔开
并且我的月和日是2.14  也就是说可以允许2位数,也可以是一位数。年嘛,我还真没考虑到如果别人输入不是4位

就是想集思广意,让大家说说该怎样限制用户输入以及判断合法性。呵呵
看看大家都有什么巧妙地方法,达到事半功倍!

如果在用户输入的时候就写上面那么多要求,吓死人了都!
作者: bhsx    时间: 2010-1-9 17:41

可以用DATE命令检测
  1. @SET /P SD=输入日期
  2. @echo.|date %SD%|find "日期">NUL&&echo 日期错误||echo ok&date %date%
复制代码

[ 本帖最后由 bhsx 于 2010-1-9 19:12 编辑 ]
作者: Seter    时间: 2010-1-9 18:04

我这里运行不了任何批处理..但是我觉得楼主可以试试09...或许会出错(set/a=0***是8进制)
我对数据合法性一直没啥感觉..数据溢出还好,注入怎么防?麻烦死个人啊,干脆不管了,反正是别人的电脑爱咋咋的...
作者: maxil    时间: 2010-1-9 21:05

原帖由 Seter 于 2010-1-9 18:04 发表
我这里运行不了任何批处理..但是我觉得楼主可以试试09...或许会出错(set/a=0***是8进制)
我对数据合法性一直没啥感觉..数据溢出还好,注入怎么防?麻烦死个人啊,干脆不管了,反正是别人的电脑爱咋咋的...

果然 当输入的月或者日是 08 或 09 时出错!!!  这个怎么解决呢?
作者: 随风    时间: 2010-1-9 21:21

参考这个帖子吧
http://www.bathome.net/thread-6913-1-3.html
作者: liupeng386    时间: 2011-8-9 16:29

可以限定输入日期格式为8位,年4月日各2位,再用批处理判断月是否大于12,日是否大于31(万一是该月只有30天的我办不到):
@echo off
:ss
cls
set /p rq=请输入8位数日期(年4位月日各2位):
if "%rq%" equ "" goto ss
set /a yue=1%rq:~4,2%-100
set /a ri=1%rq:~6,2%-100
if %yue% equ 0 echo 月错误&set rq=&pause&goto ss
if %ri% equ 0 echo 日错误&set rq=&pause&goto ss
if %yue% gtr 12 echo 月错误&set rq=&pause&goto ss
if %ri% gtr 31 echo 日错误&set rq=&pause&goto ss
pause
作者: liupeng386    时间: 2011-8-9 16:36

比上边的更精确些了,可运行来看,不够8位总报错
  1. @echo off
  2. :ss
  3. cls
  4. set /p rq=请输入日期(8位,年4月日各2位):
  5. if "%rq%" equ "" goto ss
  6. set /a yue=1%rq:~4,2%-100
  7. set /a ri=1%rq:~6,2%-100
  8. if %yue% leq 0 echo 月错误&set rq=&pause&goto ss
  9. if %yue% gtr 12 echo 月错误&set rq=&pause&goto ss
  10. if %ri% leq 0 echo 日错误&set rq=&pause&goto ss
  11. if %ri% gtr 31 echo 日错误&set rq=&pause&goto ss
  12. pause
复制代码

作者: hanyeguxing    时间: 2011-8-9 17:48

回复 10# liupeng386
  1. @echo off
  2. :Y
  3. setlocal enabledelayedexpansion
  4. set X=20120209&set "Y=!X!"
  5. if "%Y:~7,1%"=="" goto:E
  6. if "%Y:~8%" neq "" goto:E
  7. for /l %%a in (0,1,9) do if defined Y set "Y=!Y:%%a=!"
  8. if defined Y goto:E
  9. set /a Y=1%X:~0,4%-10000,M=1%X:~4,2%-100,D=1%X:~6,2%-100,"E=31+(M-M/8)%%2+^!(M-2)*(^!(Y%%4)&^!(^!(Y%%100))|^!(Y%%400)-2)","K=^!^!M&^!^!D&^!(M/13)&^!(D/E)&^!(Y/2201)&^!^!(Y/1801)"
  10. if %K%==0 goto:E
  11. pause&exit
  12. :E
  13. echo 出错&pause&endlocal&goto:Y
复制代码





欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2