Ошибка при удалении файла с помощью функции remove()

#c

#c

Вопрос:

У меня проблема с функцией remove ()

Сначала посмотрите на пример, и вы увидите проблему

 cout << "Please enter the phone number to remove" << endl << "Phone number: ";
string rphNumber;
cin >> rphNumber;
ifstream ifile("db/"   rphNumber   ".txt");
if(ifile)
  remove(("db/"   rphNumber   ".txt").c_str()); // the problem here
else
  cout << "failure" << endl;
  

Проблема в этой строке (путь к файлу), всегда функция возвращает -1, хотя файл существует

 remove(("db/"   rphNumber   ".txt").c_str());
  

Комментарии:

1. @Michael Goldshteyn: к сожалению, сообщения об ошибке нет

2. @LionKing какую платформу вы используете?

3. @FailedDev:: Я использую Visual Studio 2010 с Windows 7

Ответ №1:

Ваша проблема может заключаться в том, что у вас все еще есть ifile open в тот момент, когда вы пытаетесь его удалить. Некоторые операционные системы не позволяют удалять открытые файлы. Другая возможность заключается в том, что строка rphNumber может содержать новую строку в конце, которую вам нужно удалить перед сборкой имени файла. (Я не помню, cin делает это или нет.)

Ваша проблема определенно заключается в том, что вы пытаетесь выяснить, будет ли работать операция файловой системы. Вы не можете этого сделать. В промежутке между выполнением теста и фактической попыткой выполнить операцию другой процесс может изменить ситуацию так, что операция не будет работать, даже если ваш тест сказал, что это будет. Кроме того, возможность открыть файл — это не то же самое, что возможность удалить файл; на вашем жестком диске, вероятно, много файлов, которые вы можете открыть, но не удалить (например, /dev/null ).

Вам нужно просто выполнить операцию с файловой системой. Он сообщит вам, сработало это или нет, с его возвращаемым значением. Затем, когда это не работает, вы смотрите errno , чтобы выяснить, почему. Служебная функция C strerror (include <cstring> ) преобразует errno значение в удобочитаемое сообщение об ошибке.

Собрав все вместе, вот правильный способ написания вашей программы:

 cout << "Please enter the phone number to remove.nPhone number: ";
string rphNumber;
cin >> rphNumber;
string fname("db/"   rphNumber   ".txt");

if (remove(fname.c_str()))
    cout << "Failed to delete '" << fname << "': " << strerror(errno) << 'n';
else
    cout << ''' << fname << "' successfully deleted.n";
  

Кстати, никогда не используйте endl ; если 'n' не работает, это означает, что ваши streambufs настроены неправильно.

Комментарии:

1. Сообщение об ошибке :: не удалось удалить c://fileName.txt : в разрешении отказано

2. Это не может быть правильным, поскольку программа пытается удалить файл в каталоге с именем ‘db’. Что это на самом деле говорит?

Ответ №2:

Если remove сбой, он будет установлен errno , а также вернется -1 . Я не совсем понимаю, почему вы уверены, что это сбой, поскольку вы фактически не сохраняете возвращаемое значение в переменной.

Но, предполагая, что он возвращает -1, errno распечатайте, чтобы вы могли определить, какова фактическая ошибка, что-то вроде:

 int rc = remove(("db/"   rphNumber   ".txt").c_str());
if (rc < 0)
    perror ("could not remove file");
  

Комментарии:

1. paxdiablo:: к сожалению, сообщение об ошибке не появляется, но функция возвращает -1

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

3. @Zack, я не предлагаю это в качестве производственного исправления, просто для временного отладочного кода, чтобы выяснить проблему. В любом случае вы могли бы поместить оба этих элемента в строку, переданную perror .

4. Я думаю, что это не так раздражает в C , как в C, да. Ну, за исключением риска того, что выделение памяти под капотом будет сбиваться errno . О чем, возможно, не стоит беспокоиться. Как вы говорите, это временный отладочный код.

5. Сообщение об ошибке :: не удалось удалить c://fileName.txt : в разрешении отказано