樱花流逝
求助,关于遍历指定目录中的所有文件和子目录

废话不多说先上程序:

#include <stdio.h>
#include <tchar.h>
#include<io.h>
#include<stdlib.h>
#include *本站禁止HTML标签噢*
#include *本站禁止HTML标签噢*
using namespace std;
int ayu = 0;
int change_path(string path, stringnew_path){
int i = path.length();
new_path = "\\" + new_path + "*.*";
path.replace(i - 2, i, new_path);
return 0;
}
int find_file( string a )
{
string s1,s2;
long Handle;
s1.replace(NULL, NULL, a);
struct _finddata_t FileInfo;
cout << ayu << "\t" << endl;
if ((Handle = _findfirst(a.c_str(), &FileInfo)) == -1L){
if (_A_SUBDIR & FileInfo.attrib){
if ((strcmp(FileInfo.name, ".") != 0) &&(strcmp(FileInfo.name, "..") != 0)){
printf("%s\n", FileInfo.name);
s2.replace(NULL, NULL, FileInfo.name);
change_path(s1, s2);
ayu = ayu + 1;
find_file(s1);
}
}
}
else{
printf("%s\n", FileInfo.name);
while (_findnext(Handle, &FileInfo) == 0){
if (_A_SUBDIR & FileInfo.attrib){
if ((strcmp(FileInfo.name, ".") != 0) &&(strcmp(FileInfo.name, "..") != 0)){
printf("%s\n", FileInfo.name);
s2.replace(NULL, NULL, FileInfo.name);
change_path(s1, s2);
ayu = ayu + 1;
find_file(s1);
}
}
printf("%s\n", FileInfo.name);
}
_findclose(Handle);
}
ayu -= 1;
system("pause");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
string s;
cout << "please inupt path:";
cin >> s;
find_file(s);
return 0;

}
主要思路就是通过对find_file()的递归调用来达到遍历目录的目的(ayu变量是在检错的时候加上去的)

但是实际运行的时候出来这样的错误

变量ayu显示程序在这两个文件上重复了上千次。

然而想了好久实在不知道是哪里错了orz

樱花流逝
本帖最后由
展开Biu

本帖最后由 樱花流逝 于 2015-8-30 11:51 编辑

张全蛋 发表于 2015-8-29 23:17

先说一下,我的编译环境是 Dev-cpp + gcc 4.9.2,代码一共分为3个文件。

主体“main.cpp”:

看了你的代码后感觉获益匪浅,真的非常感谢。

[查看全文]
张全蛋
樱花流逝
展开Biu

樱花流逝 发表于 2015-8-29 20:53

嗯,发一下吧,谢谢了

我看到前面有人说调用系统API的,这里贴一个MSDN的代码示例吧,它就是调用了系统API遍历了一个目录下的全部文件和文件夹,但不包括子目录里面的内容,https://msdn.microsoft.com/en-us/library/windows/desktop/aa365200(v=vs.85).aspx 。

[查看全文]
张全蛋
樱花流逝
展开Biu

樱花流逝 发表于 2015-8-29 11:11

嗯多谢了。

我把change_path()改成了这样

int change_path(string & path, string new_path){

那个代码字体就在回复的一个按钮上能调出来。

[查看全文]
张全蛋
樱花流逝
展开Biu

樱花流逝 发表于 2015-8-29 20:53

嗯,发一下吧,谢谢了

先说一下,我的编译环境是 Dev-cpp + gcc 4.9.2,代码一共分为3个文件。

主体“main.cpp”:

[mw_shl_code=cpp,true]

/* main.cpp */

#include "find_file.h"

#define _TEST_LOCATION "F:\\图片\\*.*"

int main(void)

{

string str1 = _TEST_LOCATION;

find_file(str1);

return 0;

}

[/mw_shl_code]

头文件“find_file.h”如下:

[mw_shl_code=cpp,true]

/* find_file.h */

#pragma once

#ifndef FIND_FILE_H_

#define FIND_FILE_H_

#include *本站禁止HTML标签噢*

//void change_path(string & path, string new_parh);

using std::string;

void find_file(string path);

#endif

[/mw_shl_code]

头文件的函数实现部分“find_file.cpp”:

[mw_shl_code=cpp,true]

/* find_file.cpp */

#include "find_file.h"

#include *本站禁止HTML标签噢*

#include <string.h>

#include <io.h>

void find_file(string path)

{

using std::cout;

using std::endl;

/* 用复制构造函数,拷贝原始路径字符串 */

string originalPath(path);

string subPath;

struct _finddata_t FileInfo;

long FileHandle;

FileHandle = _findfirst(originalPath.c_str(), &FileInfo);

if (FileHandle == -1L)

{

cout << "Maybe you have input an invalid path!" << endl

<< "The invalid path is:" << originalPath;

exit(1);

}

else

{

do

{

/* 如果打开的内容是一个目录 */

if (FileInfo.attrib & _A_SUBDIR)

{

if (strcmp(FileInfo.name, ".") == 0 ||

strcmp(FileInfo.name, "..") == 0)

{

continue;

}

else

{

/* 输出当前的文件夹名 */

cout << "The subdir name is: " << FileInfo.name << endl;

/* 准备进入子目录 */

subPath = originalPath.replace(originalPath.find("*"),

4,

FileInfo.name) + "\\*.*";

/** 注意,由于调用replace方法之后,会改变originalPath的内容

* 所以这里要恢复到原始的路径内容, 不然递归回来之后,这里的

* originalPath 会影响到下一个子目录路径的生成而报错

*/

originalPath = path;

find_file(subPath);

}

}

else

{

cout << "The file name is: " << FileInfo.name << endl;

}

/* 遍历当下这个目录下一个文件(夹) */

} while(_findnext(FileHandle, &FileInfo) == 0);

_findclose(FileHandle);

}

}

[/mw_shl_code]

[查看全文]
樱花流逝
本帖最后由
展开Biu

本帖最后由 樱花流逝 于 2015-8-29 21:05 编辑

张全蛋 发表于 2015-8-29 19:35

我这边写了个测试代码,也是递归遍历的,要不要先发给你看下?

嗯,发一下吧,谢谢了

[查看全文]
张全蛋
樱花流逝
展开Biu

樱花流逝 发表于 2015-8-29 12:05

看了4楼的建议后自己又改了一下,发现按照之前那样子在那个位置改s1的话,s1的值会一直继承下去导致所有的 ...

我这边写了个测试代码,也是递归遍历的,要不要先发给你看下?

[查看全文]
樱花流逝
本帖最后由
展开Biu

本帖最后由 樱花流逝 于 2015-8-29 12:57 编辑

看了4楼的建议后自己又改了一下,发现按照之前那样子在那个位置改s1的话,s1的值会一直继承下去导致所有的文件名都连一起。
所以就改成了这个样子:
#include <stdio.h>
#include <tchar.h>
#include<io.h>
#include<stdlib.h>
#include *本站禁止HTML标签噢*
#include *本站禁止HTML标签噢*
using namespace std;
int ayu = 0;
int change_path(string & path, string new_path){
int i = path.length();
new_path = new_path + "\\*.*";
path.replace(i - 3, i, new_path);
return 0;
}

int find_file( string a ,string b )
{
string s1,s2;
long Handle;
if (b.compare("sdf.txt") != 0){ change_path(a, b); }
s1.replace(NULL, NULL, a);
ayu += 1;
cout << ayu << "\t" << s1 << "\t" << endl;
struct _finddata_t FileInfo;
if ((Handle = _findfirst(a.c_str(), &FileInfo)) == -1L){
return 0;
}else{
printf("123%s\n", FileInfo.name);
while (_findnext(Handle, &FileInfo) == 0){
if (_A_SUBDIR & FileInfo.attrib){
if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0)){
printf("%s\n", FileInfo.name);
s2.replace(NULL, NULL, FileInfo.name);
find_file(s1, s2);
ayu += -1;
}
}else{
printf("456%s\n", FileInfo.name);}
}
_findclose(Handle);
}

return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
string s;
cout << "please inupt path:";
cin >> s;
find_file(s,"sdf.txt");
system("pause");
return 0;
}
然而还是错了#pm而且总感觉越来越奇怪了@@26!!

不知为何字符串粘到一起去了==而且粘的方式还无比奇葩

[查看全文]
樱花流逝
你这个代码里有很多问题
展开Biu

张全蛋 发表于 2015-8-28 20:08

你这个代码里有很多问题,比如 change_path 来改变下一个遍历的路径,但没有用引用传参,也就是说,你调用 ...

嗯多谢了。

我把change_path()改成了这样

int change_path(string & path, string new_path){

int i = path.length();

new_path = new_path + "\\*.*";

path.replace(i - 3, i, new_path);

return 0;

}

假设path="d:\xx\*.*"; new_path="yy";

如果写成new_path = "\\" + new_path + "\\*.*";的话就要把path.replace(i - 3, i, new_path);中的3改成,(虽然之前把3写成2了。。。)

如果直接这么写的话path += new_path;的到的结果不是会变成d:\xx\*.*yy么?

弱弱的问一句。。。那个代码的字体是怎么弄出来的?

[查看全文]