Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如果文件存在,则搜索目录数组_C_File_Loops_Search - Fatal编程技术网

C 如果文件存在,则搜索目录数组

C 如果文件存在,则搜索目录数组,c,file,loops,search,C,File,Loops,Search,我有一个算法,可以查看包含多个路径的数组,并检查数组中列出的任何目录中是否存在命令(如ls、wc、cat…等)。如果在其中一个目录中找到该文件,则返回完整的目录路径 char *LookupPath(char **argv, char **dir) { /* String Name To Be Returned */ char *result; char path_name[MAX_PATH_LEN] = {0}; int i; /* Check To

我有一个算法,可以查看包含多个路径的数组,并检查数组中列出的任何目录中是否存在命令(如ls、wc、cat…等)。如果在其中一个目录中找到该文件,则返回完整的目录路径

char *LookupPath(char **argv, char **dir)
{
    /* String Name To Be Returned */
    char *result;
    char path_name[MAX_PATH_LEN] = {0};
    int i;

    /* Check To See If File Name Is Already An Absolute Path Name */
    if(*argv[0] == '/') {

    }

    /* Look In Path Directories */
    for(i = 0; dir[i] != NULL; i++) {
        strncat(path_name, dir[i], sizeof(path_name));
        strncat(path_name, "/", sizeof(path_name));
        strncat(path_name, argv[0], sizeof(path_name));
        printf("pathname: %s\n", path_name);
        result = path_name;
        if(access(result, F_OK) == 0) {
            printf("SUCCESS!\n");
            printf("result: %s\n", result);
            return result;
        }
        path_name[0] = '\0';
    }

    /* File Name Not Found In Any Path Variable */
    return NULL;
}
pathname: /usr/lib/lightdm/lightdm/ls
pathname: /usr/local/sbin/ls
pathname: /usr/local/bin/ls
pathname: /usr/sbin/ls
pathname: /usr/bin/ls
pathname: /sbin/ls
pathname: /bin/ls
SUCCESS!
result: /bin/ls
pathname: /usr/lib/lightdm/lightdm/ls

pathname: /usr/local/sbin/ls

pathname: /usr/local/bin/ls

pathname: /usr/sbin/ls

pathname: /usr/bin/ls

pathname: /sbin/ls

pathname: /bin/ls

pathname: /usr/games/ls

pathname: /usr/local/games/ls

ls
: Command Not Found!

新问题:当使用诸如ls-l之类的命令或任何其他命令时,结果运行良好,如下面的结果代码所示

char *LookupPath(char **argv, char **dir)
{
    /* String Name To Be Returned */
    char *result;
    char path_name[MAX_PATH_LEN] = {0};
    int i;

    /* Check To See If File Name Is Already An Absolute Path Name */
    if(*argv[0] == '/') {

    }

    /* Look In Path Directories */
    for(i = 0; dir[i] != NULL; i++) {
        strncat(path_name, dir[i], sizeof(path_name));
        strncat(path_name, "/", sizeof(path_name));
        strncat(path_name, argv[0], sizeof(path_name));
        printf("pathname: %s\n", path_name);
        result = path_name;
        if(access(result, F_OK) == 0) {
            printf("SUCCESS!\n");
            printf("result: %s\n", result);
            return result;
        }
        path_name[0] = '\0';
    }

    /* File Name Not Found In Any Path Variable */
    return NULL;
}
pathname: /usr/lib/lightdm/lightdm/ls
pathname: /usr/local/sbin/ls
pathname: /usr/local/bin/ls
pathname: /usr/sbin/ls
pathname: /usr/bin/ls
pathname: /sbin/ls
pathname: /bin/ls
SUCCESS!
result: /bin/ls
pathname: /usr/lib/lightdm/lightdm/ls

pathname: /usr/local/sbin/ls

pathname: /usr/local/bin/ls

pathname: /usr/sbin/ls

pathname: /usr/bin/ls

pathname: /sbin/ls

pathname: /bin/ls

pathname: /usr/games/ls

pathname: /usr/local/games/ls

ls
: Command Not Found!

然而,现在当我只使用一个简单的命令,如“ls”时,它就打开了…结果是错误的…因为出于某种原因,一个新行字符被添加到ls。。。?看来:

char *LookupPath(char **argv, char **dir)
{
    /* String Name To Be Returned */
    char *result;
    char path_name[MAX_PATH_LEN] = {0};
    int i;

    /* Check To See If File Name Is Already An Absolute Path Name */
    if(*argv[0] == '/') {

    }

    /* Look In Path Directories */
    for(i = 0; dir[i] != NULL; i++) {
        strncat(path_name, dir[i], sizeof(path_name));
        strncat(path_name, "/", sizeof(path_name));
        strncat(path_name, argv[0], sizeof(path_name));
        printf("pathname: %s\n", path_name);
        result = path_name;
        if(access(result, F_OK) == 0) {
            printf("SUCCESS!\n");
            printf("result: %s\n", result);
            return result;
        }
        path_name[0] = '\0';
    }

    /* File Name Not Found In Any Path Variable */
    return NULL;
}
pathname: /usr/lib/lightdm/lightdm/ls
pathname: /usr/local/sbin/ls
pathname: /usr/local/bin/ls
pathname: /usr/sbin/ls
pathname: /usr/bin/ls
pathname: /sbin/ls
pathname: /bin/ls
SUCCESS!
result: /bin/ls
pathname: /usr/lib/lightdm/lightdm/ls

pathname: /usr/local/sbin/ls

pathname: /usr/local/bin/ls

pathname: /usr/sbin/ls

pathname: /usr/bin/ls

pathname: /sbin/ls

pathname: /bin/ls

pathname: /usr/games/ls

pathname: /usr/local/games/ls

ls
: Command Not Found!


我不知道为什么。有没有办法把它简化为“ls”呢。我不知道为什么要在argv[0]中添加一个新行字符,而它只是一个简单的ls命令:S

您不能在循环中调用它,因为您正在修改dir字符串:strcat()通过修改将源字符串附加到目标(并且您使用dir字符串作为目标)。此外,由于没有对扩展字符串长度做任何规定,因此写入的内容超过了字符串内存的末尾,并损坏了其他内存

您需要创建一个足够长的字符数组作为局部变量,并在其中构造要测试的路径名。最好使用snprintf()而不是strcat(),并确保创建的路径适合字符串。此外,由于无法返回本地字符串,因此在成功的情况下,需要malloc()一个结果长度的新字符串,并将结果复制到其中


至于检查它是否已经是绝对的,请检查名称的第一个字母是否为“/”。您似乎已经这样做了。

我很确定有一些库可以为您这样做,但您真正的问题是,每次通过循环时,您都会附加到dir中的路径

结果是ptr

这些行实际上每次都将/argv[0]追加到路径中的每个元素 你进入循环

    result = dir[i];
    strcat(result, "/");
    strcat(result, argv[0]);
您需要创建一个临时字符缓冲区,并使用多个strcat或sprintf来填充内容。FWIW,您应该养成使用strncat或类似字符串函数和长度参数的习惯。像这样的代码是许多安全问题的开始。像这样的

     char result[PATH_MAX]; 
     strncpy(dir[i],result,length(dir[i))

是的,
strcat
似乎是这里的问题。假设
char**dir
是一个标准的字符串数组,那么在
strcat
上运行时,很可能会结束,这很糟糕

不!不
strcat
<代码>strcat分配缓冲区溢出,就像太阳分配阳光一样。。。说真的,不要

您需要在循环中分配某种缓冲区;说

char buf[BUFSIZE] = {0};
result = buf;
其中
BUFSIZE
#将
d定义为足够大(我的粗略估计:尝试300)

然后尝试以下操作:

strlcpy(buf, dir[i], BUFSIZE);
strlcat(buf, "/", BUFSIZE);
strlcat(buf, argv[0], BUFSIZE);
警告:我现在无法测试此功能;我只是觉得它行得通。不过应该可以


您是说我使用dir作为目的地,但上次我检查时,strcat是(dest,src)…我没有看到我将其用作目的地。那么正确的代码是什么您先执行“result=dir[i];”然后执行“strcat(result)”/”;所以结果与dir[i]相同。您正在修改dir[i]指向的字符串。好的,现在我有了数组char path_name[MAX_SIZE];我将如何在其中构建它比如说…使用snprintf。。。我想使用dir[I]/argv[0]…snprintf()的工作原理与printf()完全相同,只是它打印到字符串中,所以使用给定字符串的“%s/%s”格式就可以了。检查返回值(打印字符数)是否不大于MAX_SIZE,否则目标字符串被截断。另外,你应该认真阅读字符串在C中的工作原理(特别是C不知道字符串,只知道数组),否则你会继续遇到很多问题(和严重的bug,即使它看起来可以工作),就像你原来的问题一样。嘿,我已经解决了主要问题…但是请重新阅读问题。我现在有一个新问题。我已经添加了固定代码。