[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
补充一些细节,
  1. long wcstol( const wchar_t *nptr, wchar_t **endptr, intbase);
  2. 释义:将字符串类型根据不同的基转化数字形式。
  3. 其中:[in] nptr 表示要进行扫描字符串指针
  4. [out] endptr  存储扫描后无法转化的剩余的字符串
复制代码
也就是说,读取后剩余部分会覆盖掉原来的tas
下面if的意思是,假如读取后的剩余部分的第一个字符还是数字或者字母的话,那么失败
例子:1000a执行后还剩下a,所以解析失败。
而2147483648由于超出32bit正数范围,解析后tas会指向8,读进去的数字是214748364,由于现在指向的还是一个数字,if命中,命令报错。
1

评分人数

TOP

不明觉厉

QQ 20147578

TOP

本帖最后由 buyiyang 于 2023-9-25 19:15 编辑

回复 12# 老刘1号


    大概明白了,算数运算的解析字符串表达式是逐字符的,-首先被解析,被解析为操作符了,然后后面的数字2147483648被解析为操作数,操作数字符串要转长整型,过程中由于溢出遇到错误tas会指向最后停止的位置,判断指向的是数字8就会报错。

    十分感谢@老刘1号提供的源码!基于第二个源码我再详细理解一下解析过程,有几个重要的变量,bUnaryOpPossible来判断是否允许一元操作符出现,初始值为TRUE。然后c=*tas,c是TCHAR类型的,c那么就是tas字符串数组的第一个字符,然后判断c是空白、字母、数字、操作符还是变量名,空白字符删除,操作符压入操作符栈,变量名压入操作数栈,变量名存储在 lOperands 数组中的Name字段,计算表达式时从环境变量中获取其值,如果是数字就从对tas字符串进行_tcstol处理转成长整型,遇到错误就将指针指向最后停止的位置,去除tas字符串前面成功转成长整型的部分。每判断一个字符,都会tas += 1,去除tas字符串中前一个已经判断过的字符。进行do while循环中直到尾tas字符串\0。

    比如,set /a n=1+1,对于字符串"n=11+1",首先指针指向n,c为'n',判断为变量名,然后指针移到=,判断为操作符,指针移到1,判断为数字,对"11+1"进行_tcstol处理,在+遇到错误,11转成长整型作为操作数,指针移到+,判断为操作符,指针移到1,判断为数字,对"1"进行_tcstol处理,1转成长整型作为操作数,指针移到\0,循环结束。

TOP

回复 15# 老刘1号
进行_tcstol的时候c已经是一个dight了,而c=*tas,那么也就是说tas指向的字符串是数字开头的

这个是如何看出来的?

TOP

回复 19# buyiyang


    见第二个文件的69和75行

TOP

回复 20# 老刘1号


    这里从tas字符数组第一个地址开始判断每个字符是空白、字母、数字、操作符,如何得出tas指向的字符串是数字开头的?do循环中,c=*tas应该是tas字符数组的第一个字符,判断完后,然后tas += 1,再赋值c=*tas是tas字符数组的第二个字符。

TOP

回复 21# buyiyang


   可能我表述不太清晰,你可以理解为tas指向的子串(原字符串去掉了前面若干字符剩余的部分)
因为c的字符串本质上就是指向以0结尾的字节数组的指针嘛,指针+1了指向的那个字符串就变化了(相当于最前面的字符就没了)。

TOP

回复 22# 老刘1号


    可能误解你的意思了,你的意思是:c=*tas,当能进行_tcstol的时候说明c是一个dight,此时tas指向的字符串是数字开头的。明白了,我以为你说一开始的tas

TOP

返回列表