Как выполнить chdir с помощью C в среде Linux

Я новичок в программировании на c. Как я могу изменить каталог, такой как /home/jobs/$ans/xxx/, пока у меня есть $ans строка пользователя, которую я не могу chdir в программе c.

Мой скрипт ниже:

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

int main()
{
    char jdir;
    printf("Enter job directory:");  /* user input for different directories */
    scanf("jdir");
    chdir("/home/jobs/%jdir/xxx");
    system("ls -ltr");
    return(0);
}

Как изменить каталог с помощью chdir?


person user1795444    schedule 02.11.2012    source источник
comment
sprintf — это функция, которую вы хотите.   -  person OmnipotentEntity    schedule 03.11.2012


Ответы (2)


Используйте что-то вроде:

char jdir[200]
scanf("%s", &jdir);
char blah[200];
snprintf(blah, 199, "/home/jobs/%s/xxx", jdir);
chdir(blah);
person solarised    schedule 03.11.2012
comment
snprintf(blah, sizeof(blah), ...) — стандартная идиома. Вам не нужно резервировать лишний символ сверх номера, указанного в вызове. OTOH, вы можете/должны использовать if (scanf("%199s", jdir) != 1), исправляя &jdir (то же значение, другой тип) и следя за тем, чтобы строка не переполнялась (и там 199 правильно, вам нужно выделить дополнительный символ). И (как сказал @cHao), вам нужно больше места в blah, если пользователь вводит много символов в jdir. На самом деле blah должен быть как минимум на 15 символов длиннее, чем jdir. - person Jonathan Leffler; 03.11.2012
comment
Как говорится, вы можете настроить эти размеры буфера. Если бы я набрал ../jobs/./././(еще 87+ ./), похоже, это поместит меня в /home/jobs. (Да, мне скучно.) blah должно быть достаточно большим, чтобы учитывать размер ввода плюс известный текст, по крайней мере. - person cHao; 03.11.2012
comment
scanf("%s") ничуть не менее опасен, чем gets. - person zwol; 02.07.2016

Кажется слегка глупым писать эту программу на C, но если для этого есть веская причина (например, если она должна быть setuid), то вам следует быть гораздо более защищенной в этом отношении. Я бы сделал что-то вроде этого:

#define _XOPEN_SOURCE 700 /* getline */
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(void)
{
    char *jobdir = 0;
    size_t asize = 0;
    ssize_t len;

    fputs("Enter job directory: ", stdout);
    fflush(stdout);
    len = getline(&jobdir, &asize, stdin);
    if (len < 0) {
        perror("getline");
        return 1;
    }

    jobdir[--len] = '\0'; /* remove trailing \n */
    if (len == 0 || !strcmp(jobdir, ".") || !strcmp(jobdir, "..")
        || strchr(jobdir, '/')) {
        fputs("job directory name may not be empty, \".\", or \"..\", "
              "nor contain a '/'\n", stderr);
        return 1;
    }

    if (chdir("/home/jobs") || chdir(jobdir) || chdir("xxx")) {
        perror(jobdir);
        return 1;
    }
    execlp("ls", "ls", "-ltr", (char *)0);
    perror("exec");
    return 1;
}

История редактирования этого ответа продемонстрирует, насколько сложно сделать это на 100% правильно - я постоянно возвращаюсь к нему и понимаю, что забыл еще одно дело, от которого нужно защищаться.

person zwol    schedule 03.11.2012