C - 递归复制文件
C - recursively copying files
我不知道为什么,但我找不到问题出在哪里。我 运行 测试它是目录还是文件,甚至文件也被视为文件夹。
问题是,虽然 运行即使是文件循环,它也会进入目录进程并发布“file1 for directories”
代码如下:
void copie_dossier(char *doss1, char *doss2) {
struct dirent *dptr;
DIR *dp;
struct stat stbuf;
char newDest[strlen(doss2) + 1];
char tempSrc[strlen(doss1) + 1];
strcat(doss2, "/");
strcat(doss1, "/");
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
stat(doss1, &stbuf);
dp = opendir(doss1);
/*
if (!dp) {
perror("open_dir");
exit(1);
}
*/
if (!(dp))
return;
if (!(dptr = readdir(dp)))
return;
int mk = mkdir(doss2, 0777);
if (mk == -1) {
perror("create_dir");
exit(1);
}
while ((dptr = readdir(dp)) != NULL) {
struct stat stbuf2;
//stat(dptr->d_name, &stbuf2);
char *new = dptr->d_name;
if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) {
continue;
}
if (!stat(tempSrc, &stbuf2)) {
if (S_ISREG(stbuf.st_mode)) {
printf("%s for files\n", dptr->d_name);
strcat(newDest, dptr->d_name);
strcat(tempSrc, dptr->d_name);
copy_files(tempSrc, newDest);
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
}
if (S_ISDIR(stbuf.st_mode)) {
printf("%s for directory \n", dptr->d_name);
strcat(newDest, dptr->d_name);
strcat(tempSrc, dptr->d_name);
copie_dossier(tempSrc, newDest);
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
}
}
}
closedir(dp);
}
问题出在本地缓冲区的分配上:
char newDest[strlen(doss2) + 1];
char tempSrc[strlen(doss1) + 1];
strcat(doss2, "/");
strcat(doss1, "/");
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
即使是第一次使用 newDest
和 tempSrc
也会在您复制不适合目标的字符串时调用未定义的行为。 newDest
和 tempSrc
分别分配给 doss1
和 doss2
中的字符数(最后的 '[=18=]'
),但是您附加了一个额外的 /
复制前。
稍后在代码中,您连接目录条目名称,导致进一步的未定义行为。
您必须更改路径名组成的逻辑。您可以使用内存分配或全局缓冲区,在其中连接条目,同时记住路径名用于结束的位置以将其剥离回以前的状态。
在您的目录/文件名测试中还有另一个大问题:您没有 stat()
正确的路径名并且您使用单独的 stbuf2
而不是 stbuf
。您应该首先创建当前条目的路径名,将其传递给 stat()
并检查结果 stbuf
.
上的目录和文件名
这是一个改进的版本:
char *make_path(const char *path, const char *name) {
size_t len = strlen(path);
char *p = malloc(len + 1 + strlen(name) + 1);
if (p) {
strcpy(p, path);
p[len] = '/';
strcpy(p + len + 1, name);
}
return p;
}
void copie_dossier(const char *doss1, const char *doss2) {
DIR *dp;
struct dirent *dptr;
dp = opendir(doss1);
if (dp == NULL)
return;
int mk = mkdir(doss2, 0777);
if (mk == -1) {
perror("create_dir");
exit(1);
}
while ((dptr = readdir(dp)) != NULL) {
struct stat stbuf;
char *source, *dest;
if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) {
continue;
}
source = makepath(doss1, dptr->d_name);
dest = makepath(doss2, dptr->d_name);
if (!source || !dest) {
perror("makepath");
exit(1);
}
if (!stat(source, &stbuf)) {
if (S_ISREG(stbuf.st_mode)) {
printf("%s for files\n", dptr->d_name);
copy_files(source, dest);
} else
if (S_ISDIR(stbuf.st_mode)) {
printf("%s for directory \n", dptr->d_name);
copie_dossier(source, dest);
}
} else {
// should issue a diagnostic message
}
free(source);
free(dest);
}
closedir(dp);
}
您没有 post 函数 copy_files
的代码。我假设它复制了一个文件,不管名字是什么。
我不知道为什么,但我找不到问题出在哪里。我 运行 测试它是目录还是文件,甚至文件也被视为文件夹。
问题是,虽然 运行即使是文件循环,它也会进入目录进程并发布“file1 for directories”
代码如下:
void copie_dossier(char *doss1, char *doss2) {
struct dirent *dptr;
DIR *dp;
struct stat stbuf;
char newDest[strlen(doss2) + 1];
char tempSrc[strlen(doss1) + 1];
strcat(doss2, "/");
strcat(doss1, "/");
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
stat(doss1, &stbuf);
dp = opendir(doss1);
/*
if (!dp) {
perror("open_dir");
exit(1);
}
*/
if (!(dp))
return;
if (!(dptr = readdir(dp)))
return;
int mk = mkdir(doss2, 0777);
if (mk == -1) {
perror("create_dir");
exit(1);
}
while ((dptr = readdir(dp)) != NULL) {
struct stat stbuf2;
//stat(dptr->d_name, &stbuf2);
char *new = dptr->d_name;
if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) {
continue;
}
if (!stat(tempSrc, &stbuf2)) {
if (S_ISREG(stbuf.st_mode)) {
printf("%s for files\n", dptr->d_name);
strcat(newDest, dptr->d_name);
strcat(tempSrc, dptr->d_name);
copy_files(tempSrc, newDest);
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
}
if (S_ISDIR(stbuf.st_mode)) {
printf("%s for directory \n", dptr->d_name);
strcat(newDest, dptr->d_name);
strcat(tempSrc, dptr->d_name);
copie_dossier(tempSrc, newDest);
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
}
}
}
closedir(dp);
}
问题出在本地缓冲区的分配上:
char newDest[strlen(doss2) + 1];
char tempSrc[strlen(doss1) + 1];
strcat(doss2, "/");
strcat(doss1, "/");
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);
即使是第一次使用 newDest
和 tempSrc
也会在您复制不适合目标的字符串时调用未定义的行为。 newDest
和 tempSrc
分别分配给 doss1
和 doss2
中的字符数(最后的 '[=18=]'
),但是您附加了一个额外的 /
复制前。
稍后在代码中,您连接目录条目名称,导致进一步的未定义行为。
您必须更改路径名组成的逻辑。您可以使用内存分配或全局缓冲区,在其中连接条目,同时记住路径名用于结束的位置以将其剥离回以前的状态。
在您的目录/文件名测试中还有另一个大问题:您没有 stat()
正确的路径名并且您使用单独的 stbuf2
而不是 stbuf
。您应该首先创建当前条目的路径名,将其传递给 stat()
并检查结果 stbuf
.
这是一个改进的版本:
char *make_path(const char *path, const char *name) {
size_t len = strlen(path);
char *p = malloc(len + 1 + strlen(name) + 1);
if (p) {
strcpy(p, path);
p[len] = '/';
strcpy(p + len + 1, name);
}
return p;
}
void copie_dossier(const char *doss1, const char *doss2) {
DIR *dp;
struct dirent *dptr;
dp = opendir(doss1);
if (dp == NULL)
return;
int mk = mkdir(doss2, 0777);
if (mk == -1) {
perror("create_dir");
exit(1);
}
while ((dptr = readdir(dp)) != NULL) {
struct stat stbuf;
char *source, *dest;
if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) {
continue;
}
source = makepath(doss1, dptr->d_name);
dest = makepath(doss2, dptr->d_name);
if (!source || !dest) {
perror("makepath");
exit(1);
}
if (!stat(source, &stbuf)) {
if (S_ISREG(stbuf.st_mode)) {
printf("%s for files\n", dptr->d_name);
copy_files(source, dest);
} else
if (S_ISDIR(stbuf.st_mode)) {
printf("%s for directory \n", dptr->d_name);
copie_dossier(source, dest);
}
} else {
// should issue a diagnostic message
}
free(source);
free(dest);
}
closedir(dp);
}
您没有 post 函数 copy_files
的代码。我假设它复制了一个文件,不管名字是什么。