Открытие файла, заставив пользователя войти в каталог файла с помощью gets()

ВОПРОС

Открытие файла с клавиатуры Напишите программу на C, которая запрашивает у пользователя имя файла (имя также может содержать путь к каталогу) и пытается открыть файл. Программа выводит сообщение «Файл открыт!» или «Ошибка открытия файла» (программа не читает файл, а просто пытается его открыть). Используйте gets() для получения ввода пользователя

Поэтому, используя приведенный ниже код, я попытался прочитать путь к каталогу файла, а затем скопировать этот путь к каталогу файла в fopen(), а затем подтвердить, был ли файл открыт или нет. Путь к каталогу файла вводится пользователем с помощью gets().

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

int main()
{
    FILE *fp;
    char directory[100];
    printf("Please enter the directory path of the file you wish to open.\n");
    gets(directory);
    fp = fopen("%s,directory","r");
    if(fp==NULL)
    {
        printf("\nCannot open file.");
    }
    else
    {
        printf("\nFile open!");
    }
    return 0;
}   

МОЯ ПРОБЛЕМА

Независимо от того, что я вставил, это не работает, и я скопировал пути к каталогам файлов непосредственно из других программ, которые я создал, и я знаю, что они работают. Любые идеи?


person Stephen D    schedule 31.03.2016    source источник
comment
См. Почему gets() опасно использовать ?. И отругайте учителя за то, что он написал задание, в котором используется gets() — его никогда нельзя использовать.   -  person Jonathan Leffler    schedule 01.04.2016
comment
Вам нужно передать имя каталога, введенное пользователем, в fopen(), что совершенно отдельно от printf(), хотя это выглядит так, как будто вы пытаетесь смешать обозначения. Используйте: fp = fopen(directory, "r"):, который, вероятно, по-прежнему не будет работать, если данное имя является каталогом, но будет работать, если это файл. Кроме того, рекомендуется заканчивать сообщения символом новой строки вместо того, чтобы (а иногда и лучше) начинать сообщение с новой строки.   -  person Jonathan Leffler    schedule 01.04.2016
comment
Во-вторых, что сказал Джонатан Леффлер. Никогда не используйте gets ни при каких обстоятельствах. (Извините за резкость, но это важно.)   -  person Steve Summit    schedule 01.04.2016


Ответы (1)


fp = fopen("%s,каталог","r");

Это действительно сбивает с толку. Почему вы используете %s и ""? Просто используйте directory в качестве параметра напрямую. например

fopen(directory, "r"); // make sure _directory_ refers to file for this function to succeed

gets также считается опасным< /а>.

person Giorgi Moniava    schedule 31.03.2016
comment
Да, я знаю об опасности, связанной с использованием gets, просто было указано, что в программе мы должны использовать gets для чтения пользовательского ввода (я не знаю почему). Я пытался использовать только каталог в качестве параметра, и это все равно не сработает. - person Stephen D; 01.04.2016
comment
@StephenD Ну, как я уже сказал, использование только каталога не сработает, fopen нужен файл. Вам нужно объединить каталог с файлом - person Giorgi Moniava; 01.04.2016
comment
Извиняюсь, я сохранил, и поэтому это не сработало, спасибо миллион. - person Stephen D; 01.04.2016
comment
@Stephen D Я не знаю почему... потому что ваш преподаватель читает одну и ту же лекцию уже 20 лет. - person Weather Vane; 01.04.2016
comment
@StephenD Пожалуйста, дайте нам адрес электронной почты вашего учителя, чтобы мы могли рассказать ему об этом. Есть неопределенное поведение, от которого можно зависеть (и есть те, кто не согласятся со мной даже в этом), но gets — это совсем другая лига, и нет никакого оправдания тому, чтобы когда-либо использовать его в программе на C, и еще меньше оправдания для обучения этому. - person Steve Summit; 01.04.2016
comment
Основное «преимущество» использования gets() по сравнению с fgets() заключается в том, что он удаляет новую строку, что упрощает использование в подобных сценариях. Однако gets() был удален из стандарта C в C11, потому что он очень опасен. Это был один из способов обхода первого интернет-червя (поиск в Google «morris internet worm») еще в 1988 году. Использование gets_s(), если оно доступно (Microsoft), является хорошей заменой. - person Jonathan Leffler; 01.04.2016
comment
В противном случае оберните fgets() и попросите код переноса удалить новую строку. char *fgets_wrapper(char *buffer, int bufsiz, FILE *fp) { char *rp = fgets(buffer, bufsiz, fp); if (rp) buffer[strcspn(buffer, "\n")] = '\0'; return rp; }. Тестовая программа: int main(void) { char str[32]; while (fgets_wrapper(str, sizeof(str), stdin) != 0) printf("%2zu: [%s]\n", strlen(str), str); return 0; } — заголовки <stdio.h> и <stdlib.h>. - person Jonathan Leffler; 01.04.2016