DOS下遍历目录,打出文件(头晕中)

fansses 2002-07-01 04:42:55
怎么判断findfirst找到的是一个目录?如果是,那要怎么进入并搜索?
int findfirst(const char *pathname, struct ffblk *ffblk, int attrib);

这个attrib要怎么设?他的例子是0

给个遍历C盘(或所有盘)的代码吧大侠们,,,祝你们身体健康,合家欢乐.
...全文
382 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我再补充解释一下

//从任意节点开始遍历目录树,Copyright (C) Y.B.Chen
//已经在 Borland C++ 3.1 for DOS 和 Borland C++ Builder 6.0 下编译通过

#include <stdio.h>
#include <conio.h>
#include <dir.h>
#include <dos.h>
#include <string.h>

int lines = 0; //保存已经显示出几行了,如果到了一屏需要暂停
int bQuit = 0; //是否按了Esc键,如果按了Esc键,此数为非零,程序退出

void clines(void) //计算已经输出的行数,如果满一屏就暂停
{
unsigned int k;
if(lines&&(!(lines%23)))
{
printf("Press any key, or Esc to quit...");
if((k=getch())==0) //函数等待用户按键,如果=0表示功能键
k=getch()<<8; //需要再次重新调用getch判断具体是哪个键

//例如如果你按了向上移动光标的光标键,getch()返回值是0
//但是再次调用getch()时无条件返回0x48,即大写'H'的ASCII
//如果不这样编,程序就误认为是按了两次按键,一次是'\0',
//一次是'H',为了避免混淆'H'和以光标键,把移光标键移动到
//变量'k'的高8位,即k=0x4800
//最后结论: k==0x0048是大写'H',k==0x4800是移光标键

if(k==27) //Esc键的ASCII是27
bQuit = 1;
printf("\r\n");
}
lines++;
}

void dirall(const char *path) //递归函数,从path节点遍历目录树
{
struct ffblk blk;
int done;
char np[MAXPATH];

strcpy(np,path);
strcat(np,"\\*.*");
printf("==========================================\r\n"); clines();
printf("%s\r\n", path); clines();
printf("------------------------------------------\r\n"); clines();

//遍历本级目录(参数path的目录)
done = findfirst(np, &blk, FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCH|FA_DIREC);
while(!done && !bQuit)
{
if(blk.ff_attrib&FA_DIREC) //得到的文件名是目录(文件夹)
{
//分解文件的各个信息(日期、时间、长度等),显示出来
printf("%-12s <dir> %04d-%02d-%02d %02d:%02d:%02d\r\n", blk.ff_name,
(blk.ff_fdate>>9)+1980, (blk.ff_fdate>>5)&0x0f, blk.ff_fdate&0x1f,
blk.ff_ftime>>11, (blk.ff_ftime>>5)&0x3f, (blk.ff_ftime<<1)&0x3f);
}
else //得到的文件名是文件
{
//分解文件的各个信息(日期、时间、长度等),显示出来
printf("%-12s %9ld %04d-%02d-%02d %02d:%02d:%02d\r\n", blk.ff_name, blk.ff_fsize,
(blk.ff_fdate>>9)+1980, (blk.ff_fdate>>5)&0x0f, blk.ff_fdate&0x1f,
blk.ff_ftime>>11, (blk.ff_ftime>>5)&0x3f, (blk.ff_ftime<<1)&0x3f);
}
clines(); //计算是否满一屏,如果是,暂停
done = findnext(&blk); //下一个文件
}
#ifdef __WIN32__
findclose(&blk); //Windows 32比特版本的编译器要求关闭ffblk
//实际是"长文件名"系统要求必须这样做
//Windows 95 以后的版本或者NT4.0以后的版本
//如果使用了长文件名系统,在控制台模式运行
//的32位程序和控制台下调用了LFN中断的16位程序
#endif

//遍历下一级目录(参数path的下一级)
done = findfirst(np, &blk, FA_DIREC);
while(!done && !bQuit)
{
//文件名为"."和".."分别表示当前目录和上级目录,不在遍历范围,如果遍历则造成死循环
if((blk.ff_attrib&FA_DIREC) && (strcmp(blk.ff_name,".") && strcmp(blk.ff_name,"..")))
{
strcpy(np,path); //需要遍历的目录名(np) = path + blk.ff_name
strcat(np,"\\");
strcat(np,blk.ff_name);
dirall(np); //遍历下一级目录(np),(递归调用)
}
done = findnext(&blk); //下一个目录
}
#ifdef __WIN32__
findclose(&blk); //Windows 版本的编译器要求关闭ffblk
#endif
}

int main(void)
{
dirall("C:"); //从"C:"节点开始遍历
return 0;
}
LeeMaRS 2002-07-01
  • 打赏
  • 举报
回复
哎,没能在VC上调成,最后用的是Turbo C++.
写得很辛苦,50分....多加一点吧.....
-----------------------------------------------
#include <stdio.h>
#include <conio.h>
#include <dir.h>
#include <dos.h>
#include <string.h>

int lines = 0; // 目前已经输出的行数
int bQuit = 0; // 是否已经按下ESC键(退出)

void clines(void) // 控制输出数量
{
unsigned int k;
if(lines&&(!(lines%23))) // 判断是否已经输出了23行
{
printf("Press any key, or Esc to quit...");
if((k=getch())==0)
k=getch()<<8; // 这两句没怎么看懂
if(k==27) //ASCII of Esc 如果按下的是ESC键
bQuit = 1; // 做上退出的记号
printf("\r\n"); //换行
}
lines++; // 表示又输出了一行,计数器加1
}

void dirall(const char *path) // 程序的核心部分了 显示目录的函数
{
struct ffblk blk; // DOS文件控制结构体
int done; // 是否已经搜索完成
char np[MAXPATH]; // 保存路径的数组

strcpy(np,path);
strcat(np,"\\*.*");
printf("==========================================\r\n"); clines();
printf("%s\r\n", path); clines();
printf("------------------------------------------\r\n"); clines();

done = findfirst(np, &blk, FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCH|FA_DIREC);
// 调用findfirst函数,查找所有 只读 隐藏 系统 档案 目录
// 成功则返回0 , blk中放的是找到的文件/目录的信息.

while(!done && !bQuit) // 如果还能找到(!done) 而且(&&) 没要求退出 (!Quit)
{
if(blk.ff_attrib&FA_DIREC)
// 如果找到的是目录
// (用位运算,取blk.ff_attrib中FA_DIREC对应那一位)
{
printf("%-12s <dir> %04d-%02d-%02d %02d:%02d:%02d\r\n", blk.ff_name,
(blk.ff_fdate>>9)+1980, (blk.ff_fdate>>5)&0x0f, blk.ff_fdate&0x1f,
blk.ff_ftime>>11, (blk.ff_ftime>>5)&0x3f, (blk.ff_ftime<<1)&0x3f);
}
else // 否则 (是文件)
{
printf("%-12s %9ld %04d-%02d-%02d %02d:%02d:%02d\r\n", blk.ff_name, blk.ff_fsize,
(blk.ff_fdate>>9)+1980, (blk.ff_fdate>>5)&0x0f, blk.ff_fdate&0x1f,
blk.ff_ftime>>11, (blk.ff_ftime>>5)&0x3f, (blk.ff_ftime<<1)&0x3f);
}
clines(); // 输出完一行,处理
done = findnext(&blk); // 查找下一个
}
#ifdef __WIN32__
findclose(&blk); // 有点不明 大概是在Windows系统下,还需要调用的函数
#endif

done = findfirst(np, &blk, FA_DIREC); // 开始查找下一层目录

while(!done && !bQuit)
{
if((blk.ff_attrib&FA_DIREC) && (strcmp(blk.ff_name,".") && strcmp(blk.ff_name,"..")))
// 判断是否是目录 而且 排除"." 和 ".." 这两个特殊的目录
{
strcpy(np,path);
strcat(np,"\\");
strcat(np,blk.ff_name); // 组合好要搜索的下一层的路径
dirall(np); // 递归 搜索!
}
done = findnext(&blk); // 查找下一个
}
#ifdef __WIN32__
findclose(&blk); // 同上
#endif
}

int main(void)
{
dirall("C:"); //从"C:"节点开始遍历
return 0;
}
fansses 2002-07-01
  • 打赏
  • 举报
回复
谢谢哈,,,,遇到好人,没遇到鬼子,我命真好
LeeMaRS 2002-07-01
  • 打赏
  • 举报
回复
用VC吧.其它的我都用不好.呵呵.我帮你调一下那个程序,争取加点注释.等等吧:)
fansses 2002-07-01
  • 打赏
  • 举报
回复
DEV-C++
Borland C++ 5.0
VC++
 那就5.0好了
LeeMaRS 2002-07-01
  • 打赏
  • 举报
回复
你用什么编译器?
fansses 2002-07-01
  • 打赏
  • 举报
回复
名字怪怪的这位大先生,帮我一把嘛,救人一命,胜造N级XX啊

LeeMaRS 2002-07-01
  • 打赏
  • 举报
回复
没有必要害怕,他的程序只是用于控制输出的多了些,看起来有些可怕,其实没什么的,好好琢磨一下
fansses 2002-07-01
  • 打赏
  • 举报
回复
啊哟天哪。。。更加头晕。。。恐怖啊,,,,,,,,可怜一下嘛,,,新手看你的代码,不吐血三斤我看是没门
  • 打赏
  • 举报
回复
看看我编的程序:在BC31/DOS,和BCB6/Win98/XP下通过

//---------------------------------------------------------------------------
//从任意节点开始遍历目录树,Copyright (C) Y.B.Chen
//已经在 Borland C++ 3.1 for DOS 和 Borland C++ Builder 6.0 下编译通过

#include <stdio.h>
#include <conio.h>
#include <dir.h>
#include <dos.h>
#include <string.h>

int lines = 0;
int bQuit = 0;

void clines(void)
{
unsigned int k;
if(lines&&(!(lines%23)))
{
printf("Press any key, or Esc to quit...");
if((k=getch())==0)
k=getch()<<8;
if(k==27) //ASCII of Esc
bQuit = 1;
printf("\r\n");
}
lines++;
}

void dirall(const char *path)
{
struct ffblk blk;
int done;
char np[MAXPATH];

strcpy(np,path);
strcat(np,"\\*.*");
printf("==========================================\r\n"); clines();
printf("%s\r\n", path); clines();
printf("------------------------------------------\r\n"); clines();

done = findfirst(np, &blk, FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCH|FA_DIREC);
while(!done && !bQuit)
{
if(blk.ff_attrib&FA_DIREC)
{
printf("%-12s <dir> %04d-%02d-%02d %02d:%02d:%02d\r\n", blk.ff_name,
(blk.ff_fdate>>9)+1980, (blk.ff_fdate>>5)&0x0f, blk.ff_fdate&0x1f,
blk.ff_ftime>>11, (blk.ff_ftime>>5)&0x3f, (blk.ff_ftime<<1)&0x3f);
}
else
{
printf("%-12s %9ld %04d-%02d-%02d %02d:%02d:%02d\r\n", blk.ff_name, blk.ff_fsize,
(blk.ff_fdate>>9)+1980, (blk.ff_fdate>>5)&0x0f, blk.ff_fdate&0x1f,
blk.ff_ftime>>11, (blk.ff_ftime>>5)&0x3f, (blk.ff_ftime<<1)&0x3f);
}
clines();
done = findnext(&blk);
}
#ifdef __WIN32__
findclose(&blk);
#endif

done = findfirst(np, &blk, FA_DIREC);
while(!done && !bQuit)
{
if((blk.ff_attrib&FA_DIREC) && (strcmp(blk.ff_name,".") && strcmp(blk.ff_name,"..")))
{
strcpy(np,path);
strcat(np,"\\");
strcat(np,blk.ff_name);
dirall(np);
}
done = findnext(&blk);
}
#ifdef __WIN32__
findclose(&blk);
#endif
}

int main(void)
{
dirall("C:"); //从"C:"节点开始遍历
return 0;
}
fansses 2002-07-01
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <dir.h>
#include <dos.h>


void dir_list(char *dir)
{
struct ffblk ffblk;
int done;
//const char* files = "\\*.*"
//char *temp
//temp = strcat(dir, files); //???
done = findfirst(dir,&ffblk,FA_DIREC | FA_ARCH);
while (!done)
{
if (FA_DIREC == (ffblk.ff_attrib & FA_DIREC ))
{
printf("\t%s\n",ffblk.ff_name);
dir_list(&done);
}
else
{
printf("%s\n",ffblk.ff_name);
}
done = findnext(&ffblk);
}
}
void main()
{
char *p="*.*";
dir_list(p);
}



啊哟喂,,还得考虑是目录要怎么办啊?

if (FA_DIREC == (ffblk.ff_attrib & FA_DIREC ))
 那么如何得到这个目录名?
char *p=那个目录名;
findfirst(p,,&ffblk,FA_DIREC | FA_ARCH)??????????????
是吗?
LeeMaRS 2002-07-01
  • 打赏
  • 举报
回复
相当于把两个标志位FA_DIREC和FA_ARCH合并.
你要#include "dos.h"
这些是在dos.h中定义的.
LeeMaRS 2002-07-01
  • 打赏
  • 举报
回复
相当于把两个标志位FA_DIREC和FA_ARCH合并.
你要#include "dos.h"
这些是在dos.h中定义的.
fansses 2002-07-01
  • 打赏
  • 举报
回复
我看了一下|解释为按位求或,二个操作数按位求或

什么意思?在这里用了又是怎么意思?相当于|| ?
fansses 2002-07-01
  • 打赏
  • 举报
回复
done = findfirst(temp,&ffblk,FA_DIREC | FA_ARCH);

这句有问题,他说没定义FA_DIREC 和 FA_ARCH
icuc88 2002-07-01
  • 打赏
  • 举报
回复
void dir_list(char *dir)
{
struct ffblk ffblk;
int done;
const char* files = "\\*.*"
char *temp
temp = strcat(dir, files); //???
done = findfirst(temp,&ffblk,FA_DIREC | FA_ARCH);
while (!done)
{
if (FA_DIREC == (ffblk.ff_attrib & FA_DIREC ))
{
printf("\t%s\n",ffblk.ff_name);
dir_list(??????);
}
else
{
printf("%s\n",ffblk.ff_name);
}
done = findnext(&ffblk);
}
}

呵呵,不是高手,思路出来了,自己补充。
icuc88 2002-07-01
  • 打赏
  • 举报
回复
void dir_list(char *dir)
{
struct ffblk ffblk;
int done;
const char* files = "\\*.*"
char *temp
temp = strcat(dir, files); //???
done = findfirst(temp,&ffblk,FA_DIREC | FA_ARCH);
while (!done)
{
if (FA_DIREC == (ffblk.ff_attrib & FA_DIREC ))
{
printf("\t%s\n",ffblk.ff_name);
dir_list(??????);
}
else
{
printf("%s\n",ffblk.ff_name);
}
done = findnext(&ffblk);
}
}

呵呵,不是高手,思路出来了,自己补充。
songyangaaron 2002-07-01
  • 打赏
  • 举报
回复
dir/s :)
LeeMaRS 2002-07-01
  • 打赏
  • 举报
回复
设为0也就是对文件属性不做要求.

这是它的其它值:

DOS file attributes

Constant │ Description
═══════════╪═════════
FA_RDONLY │ Read-only attribute
FA_HIDDEN │ Hidden file
FA_SYSTEM │ System file
FA_LABEL │ Volume label
FA_DIREC │ Directory
FA_ARCH │ Archive

你可以在Turbo C++ 3.0的帮助中找到:)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧