There is nothing wrong with using a file, but you don't have to (and should not) store it in the same folder as the .exe file, as it may not work depending on where the .exe is located (for instance, non-admins can't write to Program Files).
Windows sets aside special folders in the user's profile just for application-generated data, so you should store the file in one of those folders instead. Use the Win32 SHGetFolderPath() or SHGetKnownFolderPath() function to discover where those special folders are located, and then you should create a sub-folder for your application's use (you can even use SHGetFolderPathAndSubDir() for that purpose).
For example:
#include <fstream>
#include <filesystem>
#include <windows.h>
#include <shlobj.h>
namespace fs = std::filesystem;
fs::path pathToMyValueFile()
{
WCHAR szPath[MAX_PATH];
if (SHGetFolderPathAndSubDirW(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, L"MyApp", szPath) != S_OK) {
throw ...;
}
return fs::path(szPath) / L"value.dat";
/* alternatively:
if (SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szPath) != S_OK)
throw ...;
fs::path folder = fs::path(szPath) / L"MyApp";
fs::create_directory(folder);
return folder / L"value.dat";
*/
}
...
int value = 0;
std::ifstream read_file(pathToMyValueFile());
if (read_file.is_open()) {
read_file >> value;
read_file.close();
}
...
int value = 5;
std::ofstream write_file(pathToMyValueFile());
if (write_file.is_open()) {
write_file << value;
write_file.close();
}
In the future, if the user ever uninstalls your app, be sure to delete that subfolder.
Otherwise, you can store the value in the Windows Registry instead. Create a new key for your application under HKEY_CURRENT_USER\Software or HKEY_LOCAL_MACHINE\Software as needed, and then you can create values inside that key.
For example:
#include <fstream>
#include <windows.h>
int readMyValue()
{
int value;
HKEY hKey;
LSTATUS lRes = RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\MyApp", 0, KEY_QUERY_VALUE, &hKey);
if (lRes == ERROR_SUCCESS)
{
DWORD size = sizeof(value);
lRes = RegQueryValueExA(hKey, "Value", NULL, NULL, (LPBYTE)&value, size);
RegCloseKey(hKey);
}
if (lRes != ERROR_SUCCESS)
{
if (lRes != ERROR_FILE_NOT_FOUND)
throw ...;
value = 0;
}
return value;
}
void saveMyValue(int value)
{
HKEY hKey;
LSTATUS lRes = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\MyApp", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL);
if (lRes == ERROR_SUCCESS)
{
DWORD size = sizeof(value);
lRes = RegSetValueExA(hKey, "Value", 0, REG_DWORD, (BYTE*)&value, sizeof(value));
RegCloseKey(hKey);
}
if (lRes != ERROR_SUCCESS)
throw ...;
/* alternatively:
if (RegSetKeyValueA(HKEY_CURRENT_USER, "Software\\MyApp", "Value", REG_DWORD, &value, sizeof(value)) != ERROR_SUCCESS)
throw ...;
*/
}
...
int value = readMyValue();
...
int value = 5;
saveMyValue(value);
If your app is uninstalled later, be sure to delete the Registry key.