everyone!
I’m trying to write a program capable of renaming files, but I’m encountering a weird issue.
When I write this:
string oldname, newname;
rename(oldname, newname);
Everything works fine. The file is renamed and there are no problems.
But then when I go ahead and try this:
int result;
result = rename(oldname, newname);
if(result)
//stuff
else
//other stuff
The "=" gets a fresh new red underline and I get an error "a value of type "void" cannot be assigned to an entity of type "int"".
I also tried
if(rename(oldname, newname))
//stuff
Then I just get "expression must have bool type (or be convertible to bool)"
Microsoft’s documentation says that the rename function returns 0 if successful and nonzero if not successful. After a lot of googling I found countless examples of code that use the second or third snippet without issue, and none of it has helped me understand what might be different in my situation. The language standard is C++17. I can’t think of any other relevant details, but just in case, here is a snippet of the actual code with all the "includes":
#include <windows.h>
#include <stdlib.h>
#include <tchar.h>
#include <vector>
#include <string>
#include <filesystem>
#include <fstream>
#include <time.h>
#include <iostream>
#include <codecvt>
#include <locale>
#include <sstream>
#include <windowsx.h>
#include <Shlobj.h>
using namespace std;
using namespace std::filesystem;
tmp_wstr = oldname + L"\n\nwill be renamed to:\n\n" + newname + L"\n\nWould you like to proceed?";
msgboxID = MessageBox(NULL, tmp_wstr.c_str(), L"Renaming...", MB_YESNO | MB_SYSTEMMODAL);
switch (msgboxID)
{
case IDYES:
result = rename(oldname, newname);
if (result)
{
error = true;
msgboxID = MessageBox(NULL, L"Unable to rename", NULL, MB_OK | MB_SYSTEMMODAL);
}
else
error = false;
break;
case IDNO:
error = true;
break;
}
Here oldname and newname are wstring instead of string, but I have tried using string and the error persists.
>Solution :
You are expecting to call the C standard library function rename with signature
int rename(const char*, const char*);
But that function would not be a viable overload for rename(oldname, newname) if oldname and newname are of type std::wstring, since std::wstring is not implicitly convertible to const char*.
So you must be calling a different function named rename. Since you used
using namespace std::filesystem;
, you are in fact calling the following overload of the C++ standard library function std::filesystem::rename with signature
void rename(const std::filesystem::path&, const std::filesystem::path&);
which is viable with your arguments, since std::filesystem::path is constructible from std::wstring (on Windows).
This function has void return type explaining the error messages. As explained in the link it doesn’t return a status code, but instead throws an exception if there is an error.