尝试在 C 中重新制作 linux 查找命令
Trying to remake linux find command in C
我的任务是重新制作 find 命令的部分功能。我尝试做的第一部分只是正常的“查找”,它列出了该目录中的所有文件和子目录。我正在使用实际的查找命令来测试我的结果。
是否有明显遗漏的内容导致我打印不正确的文件路径?
图片顺序:
C代码
预期输出
实际输出
我用来测试的目录树
void readSub (char* subDir)
{
DIR *sub_dp = opendir(subDir); //Opens directory stream
struct dirent *subDirp; //define sub directory pointer
struct stat buf; //define file status struct
char t1[] = ".";
char t2[] = "..";
char t3[] = "/";
if(sub_dp != NULL) // Was directory successfully opened
{
//read each entry one time only
while((subDirp = readdir(sub_dp)) != NULL)
{
char *temp = subDirp -> d_name; //check if first entry was a sub directory
//avoid searching for . and ..
if(strcmp(temp, t1) != 0 && strcmp(temp, t2) != 0)
{
char *tempSub = t3;
tempSub = strcat(tempSub, temp); //add / to entry name
char *temp_full_path = malloc(sizeof(char) * 2000);
temp_full_path = strcpy(temp_full_path, subDir);
strcat(temp_full_path, tempSub); //gives full path
printf("%s\n", temp_full_path);
DIR *subsubDP = opendir(temp_full_path); //try to open
if(subsubDP != NULL) //if not NULL then subsubDP is sub directory
{
closedir(subsubDP); //will get opened in recursive call
readSub(temp_full_path); //recursive call
}
}
} //end of while loop
closedir(sub_dp); //close directory stream
}
else
{
printf("Can't open directory\n");
exit(2);
}
}
int main(int argc, char **argv)
{
char *dir;
if(argc < 2)
{
dir = ".";
}
else
{
dir = argv[1];
}
readSub(dir);
exit(0);
}
问题是
tempSub = strcat(tempSub, temp); //add / to entry name
tempSub
指向t3
数组,只有2个字节。将 temp
连接到它会写入数组边界之外,这会导致未定义的行为。
您应该通过将 subDir
、t3
、temp
的长度加上空终止符的 1 来计算 temp_full_path
的总长度,并分配它.由于您只在当前循环迭代中需要它,因此您可以使用 variable-length 数组而不是 malloc()
(您的代码永远不会调用 free(temp_full_path)
)。
替换
char *tempSub = t3;
tempSub = strcat(tempSub, temp); //add / to entry name
char *temp_full_path = malloc(sizeof(char) * 2000);
temp_full_path = strcpy(temp_full_path, subDir);
strcat(temp_full_path, tempSub); //gives full path
和
char temp_full_path[strlen(subDir) + strlen(t3) + strlen(temp) + 1];
sprintf(temp_full_path, "%s%s%s", subDir, t3, temp);
我的任务是重新制作 find 命令的部分功能。我尝试做的第一部分只是正常的“查找”,它列出了该目录中的所有文件和子目录。我正在使用实际的查找命令来测试我的结果。
是否有明显遗漏的内容导致我打印不正确的文件路径?
图片顺序:
C代码
预期输出
实际输出
我用来测试的目录树
void readSub (char* subDir) { DIR *sub_dp = opendir(subDir); //Opens directory stream struct dirent *subDirp; //define sub directory pointer struct stat buf; //define file status struct char t1[] = "."; char t2[] = ".."; char t3[] = "/"; if(sub_dp != NULL) // Was directory successfully opened { //read each entry one time only while((subDirp = readdir(sub_dp)) != NULL) { char *temp = subDirp -> d_name; //check if first entry was a sub directory //avoid searching for . and .. if(strcmp(temp, t1) != 0 && strcmp(temp, t2) != 0) { char *tempSub = t3; tempSub = strcat(tempSub, temp); //add / to entry name char *temp_full_path = malloc(sizeof(char) * 2000); temp_full_path = strcpy(temp_full_path, subDir); strcat(temp_full_path, tempSub); //gives full path printf("%s\n", temp_full_path); DIR *subsubDP = opendir(temp_full_path); //try to open if(subsubDP != NULL) //if not NULL then subsubDP is sub directory { closedir(subsubDP); //will get opened in recursive call readSub(temp_full_path); //recursive call } } } //end of while loop closedir(sub_dp); //close directory stream } else { printf("Can't open directory\n"); exit(2); } } int main(int argc, char **argv) { char *dir; if(argc < 2) { dir = "."; } else { dir = argv[1]; } readSub(dir); exit(0); }
问题是
tempSub = strcat(tempSub, temp); //add / to entry name
tempSub
指向t3
数组,只有2个字节。将 temp
连接到它会写入数组边界之外,这会导致未定义的行为。
您应该通过将 subDir
、t3
、temp
的长度加上空终止符的 1 来计算 temp_full_path
的总长度,并分配它.由于您只在当前循环迭代中需要它,因此您可以使用 variable-length 数组而不是 malloc()
(您的代码永远不会调用 free(temp_full_path)
)。
替换
char *tempSub = t3;
tempSub = strcat(tempSub, temp); //add / to entry name
char *temp_full_path = malloc(sizeof(char) * 2000);
temp_full_path = strcpy(temp_full_path, subDir);
strcat(temp_full_path, tempSub); //gives full path
和
char temp_full_path[strlen(subDir) + strlen(t3) + strlen(temp) + 1];
sprintf(temp_full_path, "%s%s%s", subDir, t3, temp);