C - 将 argv[1] 附加到 unix PATH 的末尾

C - append argv[1] to end of unix PATH

我正在尝试编写一个 C 程序来解析 UNIX "PATH" 变量,并检查命令行参数文件 (argv[1]) 是否存在于该路径上的任何地址。唯一似乎不起作用的是当我尝试将“/”附加到 temp,然后将 argv[1] 附加到它时。在 while 循环中,temp 成为 PATH 变量的下一个子路径,然后它检查在命令行中输入的文件名是否存在于该路径上。将“/”附加到 temp 的末尾,然后将 argv[1] 附加到它的末尾的最佳方法是什么?

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

 void append(char* s, char c)
   {
        int len = strlen(s);
        s[len] = c;
        s[len+1] = '[=10=]';
  }

int main(int argc, char* argv[]){
    const char* path = getenv("PATH");
    char* temp;
    FILE *file;
    char sym = '/';

    temp = strdup(path);
    temp = strtok(temp,":");

    while(temp != NULL){
        printf("%s\n",temp);
        //add "/argv[1]" to temp
        append(sym,temp);
        strcat(argv[1],temp);
        printf("%s",temp);
        file = fopen(temp,"r");
        if(file == NULL){
         printf("ERROR: File \"%s\" does not exist.",temp);
        }
        else{
           printf("Success! File \"%s\" exists.",temp);
        } 
        temp = strtok(NULL,":");
    }

    printf("%s",temp);




     return 0;
}

这是一个没有 'append' 功能的工作版本:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( int argc, char* argv[] ) {
    char* path = getenv("PATH");
    char* temp;
    FILE *file;
    char tmp_file[100];

    temp = strtok(path,":");

    while ( temp != NULL ) {
        printf("temp: %s\n", temp);

        sprintf( tmp_file, "%s/%s", temp, argv[1] );
        printf("tmp_file: %s\n", tmp_file);

        file = fopen(tmp_file,"r");
        if ( file == NULL ) {
          printf("ERROR: File \"%s\" does not exist.\n", tmp_file);
        }
        else{
          printf("SUCCESS! File \"%s\" exists.\n", tmp_file);
        }
        temp = strtok(NULL,":");
    }

    return 0;
}

(你也可以使用 asprintf 而不是 sprintf,但是不要忘记释放分配的内存)

您不应修改 temp,因为您会干扰 strtok。 您的代码的主要问题是管理文件名 char 字符串的存储。如果你想构建一个新的字符串,它是路径、'/' 和 argv[1] 的串联,你需要一个存储空间。最简单的解决方案是为此使用数组。让它足够长。

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
    char* path = strdup(getenv("PATH")); // <-- copy the path string
    char* temp;
    FILE *file;
    char fileName[1024]; // <-- Storage for the file name

    temp = strtok(path,":");
    while(temp != NULL)
    {
        printf("temp: %s\n", temp);

        sprintf(fileName, "%s/%s", temp, argv[1]);
        printf("fileName: %s\n", tmp_file);

        file = fopen(fileName,"r");
        if ( file == NULL )
            printf("ERROR: File \"%s\" does not exist.\n", fileName);
        else
            printf("SUCCESS! File \"%s\" exists.\n", fileName);

        temp = strtok(NULL,":");
    }
    free(path); // <-- delete the modified copy of path
    return 0;
}

我们需要复制路径字符串,因为 strtok 会修改它。它将“:”替换为“\0”。这就是 strdup 的原因。

fileName 被定义为一个大的 char 数组,可以包含 temp / 和 argv[1] 的串联。为了完全正确,我们应该检查 strlen(temp)+1+strlen(argv[1]) < 1024 以确保我们没有缓冲区溢出。

sprintf 是格式化的打印到缓冲区中的,它将为我们进行字符串连接。第一个参数是缓冲区,第二个是格式,其余是参数。格式是由 / 字符分隔的两个字符串。