中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-06-14 18:54
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [挑战6]:硬盘容量的计算。难度[☆☆☆]
楼 主 [挑战6]:硬盘容量的计算。难度[☆☆☆] 发表于 2007-05-08 23:04 ·  中国 广东 广州 海珠区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
呵呵,这一期的挑战系列没有准时在周一出现,请大家原谅(因工作繁忙,跟着几位大侠级

的人物学习调试设备,没有时间啊)

好了,该扯的也扯了,下面进入正题(硬盘容量的计算)

现在有 一 个硬盘,但我们不知道这个硬盘分了几个区,每个区的容量是多大,剩余

空间又几何。
假设这个硬盘的空间为:300G ,按照硬盘厂商的划分标准就是:
300*1000*1000*1000 的容量。
硬盘分为 4 个区,其中
盘符 总容量 剩余容量
-------------------------------------------------------------------------------
C: 20*1024*1024*1024 1000*1024*1024
D: 40*1024*1024*1024 30*1024*1024*1024
E: 80*1024*1024*1024 60*1024*1024*1024
剩余的为 F: 盘 我们已经知道 F:已经使用了 20*1024*1024*1024 的容量。。
-------------------------------------------------------------------------------
那么现在的问题是:F: 的实际容量是多大?

要求:将上述文件存为: Drivers.txt

从文件中读取这个 硬盘容量的文件,并进行计算。

对容量的计算要求采用 4 舍 5 入的法则,基本单位为M ,不足 1G 的计算剩余容量的实际

大小(精确到 M ),过 1G 的单位为 G ,但要求精确到小数点后三位。

程序使用要求:CMD(可以使用第三方工具,可以结合vbs来做,也可以单独使用vbs来完成)

采用了第三方工具完成目标的(积分为:2分)
完全独立使用cmd完成的(积分为:5分,满分)

难点:提取出正确容量的朋友:1分
正确使用除法运算的朋友,1分
精确单位使用良好的:1分
获取F盘正确容量的 2分。
Drivers.txt
-------------------------------------------------------------------------------
C: 20*1024*1024*1024 1000*1024*1024
D: 40*1024*1024*1024 30*1024*1024*1024
E: 80*1024*1024*1024 60*1024*1024*1024
F: ????? (???-20*1024*1024*1024)
-------------------------------------------------------------------------------
set "Volume_C=" ;精确到字节
set "Volume_D="
set "Volume_E="
set "Volume_F="
set "Real_Volume_C=" 精确到M or G
Dividend:被除数
Divisor:除数
Quotient:商

好了,下面就开始做题了。。

要求输出

C: %Volume_C%(%Real_Volume_C% ) 此处的M or G 只能存在一个。
d: %Volume_D%(%Real_Volume_D% )
e: %Volume_E%(%Real_Volume_E% )
f: %Volume_F%(%Real_Volume_F% )

输出:
例如: c: 1048576(1000M)
d: 32212254720(30G)
小于1G容量的用 M 做单位
大于1G容量的用 G 做单位

[ Last edited by flyinspace on 2007-5-9 at 01:23 PM ]
知,不觉多。不知,乃求知
2 发表于 2007-05-09 00:13 ·  中国 广东 广州 白云区 电信
高级用户
★★★
潜水修练批处理
积分 788
发帖 366
注册 2006-12-31 02:43
UID 75048
性别 男
状态 离线
取得系统所有分区的空间(单位:字节)可以使用下面的代码,至于精确的计算超大数字太麻烦了,留待下一位-_-
@echo off
setlocal ENABLEDELAYEDEXPANSION
for /f "skip=1 delims=" %%i in ('fsutil fsinfo drives ^| more') do (
set a=%%i
for /f "skip=1 delims=" %%a in ('wmic LOGICALDISK where Caption^="!a:~-3,-1!" get size') do echo !a:~-3,-2! %%a
)
pause


[ Last edited by dikex on 2007-5-9 at 12:36 AM ]
正在潜水修练的批处理小白
3 发表于 2007-05-09 09:46 ·  中国 广东 广州 白云区 电信
高级用户
★★
积分 846
发帖 247
注册 2006-10-27 12:03
UID 68504
性别 男
来自 湖南==》广东
状态 离线
楼上似乎理解错了楼主的意思了.
1F的题目看起来象计算题多点.
而不是查询硬盘的.
4 发表于 2007-05-09 09:50 ·  中国 广东 广州 天河区 电信
金牌会员
★★★★
一叶枝头,万树皆春
积分 2,564
发帖 1,127
注册 2006-12-25 22:57
UID 74552
性别 男
状态 离线
你要标明是什么文件系统,这对计算最后可用空间的精度有影响
5 发表于 2007-05-09 11:54 ·  中国 新疆 乌鲁木齐 电信
高级用户
★★★
Autowalk
积分 845
发帖 375
注册 2007-03-03 01:58
UID 80606
性别 男
状态 离线
这道题对什么文件系统有关系吗?纯粹的数字乘乘除除而已。
难点在于读取文本啊,用P处理相对好读点,但是数值太大无法计算
用VBS可以计算但读取有点困难。
6 发表于 2007-05-09 12:23 ·  中国 广东 广州 天河区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
To youxi01:
主要是查询硬盘的容量(表面上是有了大数运算,但在这里,是可以通过一系列的方法避过的。)
To everest79:
兄想太多了,只是为了考察综合能力(若是真的不取巧的话,里面的内容是包含了加减乘除取余运算的)
那么在这里,就会涉及到子程序的调用问题,因为大量的四则运算若还是把加减乘除运算放在一起的话,代码的长度不敢想象:)
代码写得漂亮的,flyinspace在此另外加 3 分(难点在:合理搭配上,不需要每一句话的注释,但需要在子程序前标明这个子程序是做什么用的,刚用c++写了一个四则运算的小程序,正好来调用这每一个子程序,并看是否正确。)
ps:现在越来越感觉到算法的重要性了。大家在写这个脚本的时候,可以去网上,推荐CSDN查找大数运算的帖子。
知,不觉多。不知,乃求知
7 发表于 2007-05-09 13:13 ·  中国 新疆 乌鲁木齐 电信
高级用户
★★★
Autowalk
积分 845
发帖 375
注册 2007-03-03 01:58
UID 80606
性别 男
状态 离线
我插一句,省略了读取文本。呵呵
只是有些不太理解LZ题目的意思。。。



'C盘
uscb=20*1024*1024*1024-1000*1024*1024
uscm=uscb/1024/1024
uscg=uscm/1024
uscg=round(uscg,3)

alcb=20*1024*1024*1024
alcm=alcb/1024/1024
alcg=alcm/1024
alcg=round(alcg,3)

frcb=1000*1024*1024
frcm=frcb/1024/1024
frcg=frcm/1024
frcg=round(frcg,3)

'D盘
usdb=40*1024*1024*1024-30*1024*1024*1024
usdm=usdb/1024/1024
usdg=usdm/1024
usdg=round(usdg,3)

aldb=40*1024*1024*1024
aldm=aldb/1024/1024
aldg=aldm/1024
aldg=round(aldg,3)

frdb=30*1024*1024*1024
frdm=frdb/1024/1024
frdg=frdm/1024
frdg=round(frdg,3)

'E盘
useb=80*1024*1024*1024-60*1024*1024*1024
usem=useb/1024/1024
useg=usem/1024
useg=round(useg,3)

aleb=80*1024*1024*1024
alem=aleb/1024/1024
aleg=alem/1024
aleg=round(aleg,3)

freb=60*1024*1024*1024
frem=freb/1024/1024
freg=frem/1024
freg=round(freg,3)


'F盘
usfb=20*1024*1024*1024
usfm=usfg/1024/1024
usfg=usfm/1024
usfg=round(usfg,3)

alfb=300*1024*1024*1024-alcb-aldb-aleb
alfm=alfb/1024/1024
alfg=alfm/1024
alfg=round(alfg,3)

frfb=alfb-usfb
frfm=frfg/1024/1024
frfg=frfm/1024
frfg=round(frfg,3)




msgbox "C盘总大小: "&alcg&"G"&" "&alcm&"M"&" "&alcb&"B"&chr(10)&"C盘已用空间:"&uscg&"G"&" "&uscm&"M"&" "&uscb&"B"&chr(10)&"C盘可用空间:"&frcg&"G"&" "&frcm&"M"&" "&frcb&"B"&chr(10)&chr(10)&"D盘总大小 :"&aldg&"G"&" "&aldm&"M"&" "&aldb&"B"&chr(10)&"D盘已用空间:"&usdg&"G"&" "&usdm&"M"&" "&usdb&"B"&chr(10)&"D盘可用空间:"&frdg&"G"&" "&frdm&"M"&" "&frdb&"B"&chr(10)&chr(10)&"E盘总大小 :"&aleg&"G"&" "&alem&"M"&" "&aleb&"B"&chr(10)&"E盘已用空间:"&useg&"G"&" "&usem&"M"&" "&useb&"B"&chr(10)&"E盘可用空间:"&freg&"G"&" "&frem&"M"&" "&freb&"B"&chr(10)&chr(10)&"F盘总大小 :"&alfg&"G"&" "&alfm&"M"&" "&alfb&"B"&chr(10)&"F盘已用空间:"&usfg&"G"&" "&usfm&"M"&" "&usfb&"B"&chr(10)&"F盘可用空间:"&frfg&"G"&" "&frfm&"M"&" "&frfb&"B",vbinformation,"$$$夜七制作$$$"


8 发表于 2007-05-09 13:15 ·  中国 新疆 乌鲁木齐 电信
高级用户
★★★
Autowalk
积分 845
发帖 375
注册 2007-03-03 01:58
UID 80606
性别 男
状态 离线
额……C盘可用空间好像写错了
9 发表于 2007-05-09 23:50 ·  中国 广东 清远 联通
高级用户
★★
积分 846
发帖 247
注册 2006-10-27 12:03
UID 68504
性别 男
来自 湖南==》广东
状态 离线
那楼主的意思是:

先读取盘数,然后把前面的盘符的容量等读出来,留着最后一个要算(就是不准读)是这个意思吗?
10 发表于 2007-05-10 16:51 ·  中国 山东 枣庄 滕州市 联通
初级用户
积分 61
发帖 32
注册 2007-05-09 17:09
UID 87974
性别 男
状态 离线
学习
11 发表于 2007-05-10 17:19 ·  中国 广东 广州 天河区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
Originally posted by youxi01 at 2007-5-9 11:50 PM:
那楼主的意思是:

先读取盘数,然后把前面的盘符的容量等读出来,留着最后一个要算(就是不准读)是这个意思吗?

嗯,是呀。。

所有的项目都给出了条件呢。。

用四则运算就可以求出来的。。
知,不觉多。不知,乃求知
12 发表于 2009-01-10 18:11 ·  中国 广东 深圳 电信
初级用户
★★
积分 185
发帖 88
注册 2008-05-12 18:46
UID 118511
性别 男
状态 离线
能发一个在VISTA下也可以用的吗?
13 发表于 2009-01-11 23:04 ·  中国 广东 东莞 电信
银牌会员
★★★
批处理编程迷
积分 1,916
发帖 752
注册 2008-12-28 04:30
UID 135147
性别 男
来自 广西
状态 离线
@echo off&setlocal enabledelayedexpansion
::for 内的临时变量用_v1,_v2,_v(n)
::disk=硬盘总容量/1024
::_n=分区数

::for1 读邓正确的字符串,if 是盘f:,去除??-()等符号
:: _d:盘符 _zc:总容量串 _yc:已用空间串

::for2 字符串分段
:: _zt:总容量串头部分 _zw:尾 _yt:已用空间串头部分 _yw:尾

::for3 计算F:总空间及剩余空间
:: 使用临时变量 _v1,_v2,_v3

::for4 处理以M/G为单位的结果
:: _zm:总容量 _ym:已用空间 _sm:乘余空间

::for5 处理成字节(B),兆M/G
:: _zb:总字节B _yb:已用字节B _sb:剩余字节

::for6 显示输出


echo off
set /a disk=300*1024*1024

::for1 读正确的数字串,去除??()等符号
set _n=0
echo.读入数据&echo.************************************
for /f "tokens=1,2,3* delims= " %%i in ('findstr : drivers.txt') do (
set /a _n+=1&echo %%i %%j %%k
set _v1=%%i&set _v2=%%j&set _v3=%%k
if "!_v1!"=="F:" set _v2=!_v2:?=!&set _v3=!_v3:*-=!&set _v3=!_v3:^)=!&set _y!_n!=!_v3!
set _d!_n!=!_v1!&set _z!_n!=!_v2!&set _s!_n!=!_v3!
)
echo.************************************&echo.&echo.

::for2 数字串分段处理
:: _zt:总容量串头部分 _zw:尾 _yt:已用空间串头部分 _yw:尾
for /l %%a in (1,1,!_n!) do (
set _v2=!_z%%a!&set _v3=!_s%%a!&set _v4=!_y%%a!
set _zt%%a=!_v2:~0,-5!
set _zw%%a=!_v2:~-4!
set _st%%a=!_v3:~0,-5!
set _sw%%a=!_v3:~-4!
set _yt%%a=!_v4:~0,-5!
set _yw%%a=!_v4:~-4!
)


::for3 计算F:总空间及剩余空间
:: 使用临时变量 _v1,_v2,_v3
set _v1=
for /l %%a in (1,1,!_n!) do (
set /a _zt%%a=!_zt%%a!&set /a _st%%a=!_st%%a!&set /a _yt%%a=!_yt%%a!
if "!_d%%a!"=="F:" (set /a _zt%%a=!disk!-!_v1!&set /a _st%%a=!_zt%%a!-!_yt%%a!&set _zw%%a=!_yw%%a!) else (set /a _yt%%a=!_zt%%a!-!_st%%a!&set _yw%%a=!_zw%%a!&set /a _v1=!_v1!+!_zt%%a!)
)


::for4 计算以M单位,大于1000M以G为单位的结果
:: _zm:总容量 _sm:乘余空间 _ym:已用空间
for /l %%a in (1,1,!_n!) do (
set /a _zm%%a=!_zt%%a!/1024&set /a _sm%%a=!_st%%a!/1024&set /a _ym%%a=!_yt%%a!/1024
if !_zm%%a! leq 1000 (set _zm%%a=^(!_zm%%a!M^)) else (set /a _zm%%a=!_zm%%a!/1024 & set _zm%%a=^(!_zm%%a!G^))
if !_sm%%a! leq 1000 (set _sm%%a=^(!_sm%%a!M^)) else (set /a _sm%%a=!_sm%%a!/1024 & set _sm%%a=^(!_sm%%a!G^))
if !_ym%%a! leq 1000 (set _ym%%a=^(!_ym%%a!M^)) else (set /a _ym%%a=!_ym%%a!/1024 & set _ym%%a=^(!_ym%%a!G^))
)


::for5 处理成字节显示(B)
:: _zb:总B _yb:已用B _sb:剩余字节
for /l %%a in (1,1,!_n!) do (
rem 把%1 乘以 %2 放入%3所指的变量中
call :sub !_zt%%a! !_zw%%a! _zb%%a
call :sub !_st%%a! !_sw%%a! _sb%%a
call :sub !_yt%%a! !_yw%%a! _yb%%a
)

::for6 显示输出
echo.硬盘数据:
echo._______________________________________________________________________________
for /l %%a in (1,1,!_n!) do (echo.!_d%%a! 总容量:!_zb%%a!!_zm%%a! 剩余:!_sb%%a!!_sm%%a! 已用:!_yb%%a!!_ym%%a!)
echo._______________________________________________________________________________
pause
goto :eof

:sub
set _v1=%1&set _v2=%2&set _v3=%3
set /a _vt=!_v1:~0,-5!*!_v2!
set /a _vw=!_v1:~-5!*!_v2!
set _vx=!_vt!00000
set /a _vy=!_vx:~-9!+!_vw!
set _vx=!_vx:~0,-9!
set _v4=!_vy:~0,-9!
if not "!_va!"=="" set /a _vx=!_vx!+!_v4!
set !_v3!=!_vx!!_vy!

goto :eof

[ Last edited by netbenton on 2009-1-11 at 23:07 ]
精简
=> 个人网志
14 发表于 2009-01-12 09:40 ·  中国 北京 联通
银牌会员
★★★
积分 1,287
发帖 634
注册 2007-05-02 15:06
UID 87277
性别 男
来自 cmd.exe
状态 离线
DISKPART> list disk

外部命令的定义还没有...就这样了...
15 发表于 2009-01-12 14:46 ·  中国 广东 东莞 电信
银牌会员
★★★
批处理编程迷
积分 1,916
发帖 752
注册 2008-12-28 04:30
UID 135147
性别 男
来自 广西
状态 离线
不解:
或许还不了解楼主的意思!
还要定义什么外部命令呀?
精简
=> 个人网志
论坛跳转: