chdir(‹каталог›) не меняет каталог: Нет такого файла или каталога

Я хочу создать простую программу на С++, которая меняет каталог.

int main(int argc, char * argv[]){
//...
char input[256];
char *command;

//read command
fgets(input, 256, stdin);

// CODE ADDED WITH HELP
command = strchr(input, '\n');
    
if(command){
    *command = '\0';
}
// CODE ADDED WITH HELP

if(strncmp(input, "cd ",3)==0){
    strtok(input, " ");
    command = strtok(NULL, "\0");
    if(chdir(command) != 0){
        perror("Error while changing directory. Please try again!");
    }
}
//...
}

В приведенной выше программе вы можете увидеть код между комментариями CODE ADDED WITH HELP. Это было добавлено после. Программа работает сейчас, но я пытаюсь понять, почему она работает сейчас и почему раньше не работала.

Если вы думаете, что часть кода добавлена, я получаю сообщение об ошибке Нет такого файла или каталога при попытке изменить каталог. После того, как я получил некоторую помощь и добавил пару строк кода, теперь я могу успешно менять каталоги.

Я пытаюсь понять, что именно делает этот фрагмент кода в контексте того, чего я пытаюсь достичь, и почему он не работает без него.


person NimeQu    schedule 23.04.2021    source источник


Ответы (1)


fgets(input, 256, stdin);

При этом читается одна строка текста, включая завершающий символ новой строки. Клавиша Enter генерирует символ новой строки, который является частью ввода.

chdir(command);

Если не будут приняты дополнительные меры, завершающий символ новой строки останется в command.

Золотое правило компьютерного программирования гласит: ваш компьютер всегда будет делать именно то, что вы ему говорите, а не то, что вы от него хотите. Итак, допустим, у вас есть подкаталог с именем book, и вы набрали book в качестве входных данных для своей программы.

По причинам, объясненным выше, содержимое command будет "book\n", и будет предпринята попытка изменить текущий каталог на каталог с именем "book\n", то есть книгой, за которой следует символ новой строки. Это будет то, что вы будете говорить своему компьютеру делать. Поскольку такого каталога нет, ваш компьютер не сможет выполнить ваш запрос.

Добавленный код просто находит завершающий символ новой строки, который всегда будет последним введенным символом, и заменяет его на '\0'. Показанный код использует строки в стиле C, которые заканчиваются символом '\0' (исходный ввод чтения заканчивается символом новой строки, а fgets услужливо добавляет после этого исходный символ '\0', который может покоиться с миром). Конец.

person Sam Varshavchik    schedule 23.04.2021
comment
Спасибо, я понимаю. Последний вопрос: зачем мне нужно if-условие if(command).... Какова цель этого? - person NimeQu; 23.04.2021
comment
Это последняя деталь, вишенка на торте. Можно завершить ввод не нажатием Enter, а нажатием клавиши, которое генерирует условие конца файла, обычно CTRL-Z или CTRL-D, в зависимости от операционной системы. Это заканчивается тем, что ввод читается без завершающего символа новой строки. Или ввод в программу, стандартный ввод, может быть даже не терминалом, а перенаправлением из файла, который не заканчивается символом новой строки. Итак, в этом случае поиск '\n' не удался. - person Sam Varshavchik; 23.04.2021