I have a C++ program that reads a config file and gets the directories.
What I want to do now is to execute an .exe program using the directory settings from the config file.
Here is a piece of my code:
int main(){
ConfigFile cfg("htbaseconfig.properties");
bool exists = cfg.keyExists("backuplocation");
exists = cfg.keyExists("logdir");
exists = cfg.keyExists("execdir");
exists = cfg.keyExists("fulldir");
exists = cfg.keyExists("incdir");
exists = cfg.keyExists("appdir");
std::string bkploc = cfg.getValueOfKey<std::string>("backuplocation");
std::cout << "Backup Location: " << bkploc << "\n";
std::string bkplogdir = cfg.getValueOfKey<std::string>("logdir");
std::cout << "Log Location: " << bkplogdir << "\n";
std::string bkpexec = cfg.getValueOfKey<std::string>("execdir");
std::cout << "Exec Directory: " << bkpexec << "\n";
std::string bkpfulldir = cfg.getValueOfKey<std::string>("fulldir");
std::cout << "Full Directory: " << bkpfulldir << "\n";
std::string bkpappdir = cfg.getValueOfKey<std::string>("appdir");
std::cout << "Real app Directory: " << bkpappdir << "\n\n\n";
for( ; ; ) {
Sleep(6000);
ShellExecute(NULL, L"open", , L"C:\\teste.htm", NULL,SW_SHOWNORMAL);
}
std::cin.get();
return (0);}
Inside the ShellExecute, I wanted to execute the following line parsing the config options:
$execdir/program.exe $logdir/log.txt $bkpappdir $bkploc
How do I do this? I want to execute my program with the variables I get on std::cout.
You must pass to ShellExecute, instead of the second NULL, a string (c string, a char[]) that contains all parameters, like if you are passing them to the command line.
So Will be something like
ShellExecute(NULL, L"open", , L"C:\\teste.htm", "option=param option2=param2",SW_SHOWNORMAL);
Depends on how you parse them (or how they are parsed) from the other exe file
Related
I am trying to stream the data in the retrieved s3 file into a local file on disk. However, when I try my current code, I do not get a file stored on my computer, or in any location near the code.
I first request the object from s3 using a getObjectOutcome. After success, I want to create an ofstream and redirect the objects stream buffer to my local object so that I can create a file on disc. However, the following code does not create a file on my computer. What am I doing wrong?
Here is the get object function:
bool GetObject(const Aws::String& objectKey,
const Aws::String& fromBucket,
const Aws::Client::ClientConfiguration& clientConfig) {
Aws::S3::S3Client client(clientConfig);
Aws::S3::Model::GetObjectRequest request;
request.SetBucket(fromBucket);
request.SetKey(objectKey);
Aws::S3::Model::GetObjectOutcome outcome =
client.GetObject(request);
if (!outcome.IsSuccess()) {
const Aws::S3::S3Error& err = outcome.GetError();
std::cerr << "Error: GetObject: " <<
err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
}
else {
std::cout << "Successfully retrieved '" << objectKey << "' from '"
<< fromBucket << "'." << std::endl;
std::ofstream localfile;
localfile.open(objectKey.c_str(), std::ios::out | std::ios::binary);
auto retrieved = outcome.GetResult().GetBody().rdbuf();
localfile << retrieved;
std::cout << "Done!";
}
return outcome.IsSuccess();
}
Here is an image of the memory for local file and retrieved:
Would someone teach me what I am doing this wrong, or how to correctly download data from s3 to disc?
Thanks.
I tried downloading some data from s3 to disc. I am having trouble outputting this data via stream buffer to local file. I have been looking online and cannot find a similar problem.
Update:
I am now on my second day of trying to figure this out to no avail. For some reason, the code will not even output a file after it has been created to the directory I have set up for the .nc files to be written to.
I have tried the following updates:
bool GetObject(const Aws::String& objectKey,
const Aws::String& fromBucket,
const Aws::Client::ClientConfiguration& clientConfig) {
Aws::S3::S3Client client(clientConfig);
Aws::S3::Model::GetObjectRequest request;
request.SetBucket(fromBucket);
request.SetKey(objectKey);
Aws::S3::Model::GetObjectOutcome outcome =
client.GetObject(request);
if (!outcome.IsSuccess()) {
const Aws::S3::S3Error& err = outcome.GetError();
std::cerr << "Error: GetObject: " <<
err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
}
else {
std::cout << "Successfully retrieved '" << objectKey << "' from '"
<< fromBucket << "'." << std::endl;
//create the filename, which will be the objectKey
std::string local_file_name = "./netcdf/" + objectKey;
std::ofstream local_file(local_file_name, std::ios::binary);
auto &retrieved = outcome.GetResult().GetBody();
local_file << retrieved.rdbuf();
std::cout << "Done!";
}
return outcome.IsSuccess();
}
Then, after opening the ./netcdf folder, there is no output.
Here is the file structure inside my project for reference with the code:
I am still confused as to what I need to do here.
Thank you for all of the help you can offer!
You are using a folder with "./" at the front. This means that the file will be relative to the current working directory (cwd) of the binary. That is likely not the src folder
Just to get past your problem, use a full absolute path to see if the rest of your code works.
Also, try adding
// You need "#include <filesystem>" for the next line
cout << std::filesystem::current_path();
To see where the files you made might be
I am trying to open a json file that I will be working with in C++. Code that I have used successfully before fails to open the file. I am using Visual Studio 2017 on Windows 10 Pro with JSON for Modern C++ version 3.5.0.
I have a very simple function, which is supposed to open a file as input to a json object. It appears to open the file, but aborts when writing it to the json object. Originally the file to be opened was in another directory, but I moved it into the same directory as the executable while testing...but it didn't help.
Here is the very short function that fails:
json baselineOpenAndRead(string fileName) //passed string used for filename
{
json baseJObject;
cout << "we have a baseJObject" << endl;
//ifstream inFileJSON("test_file.json"); // Making this explicit made no difference
ifstream inFileJSON;
inFileJSON.open("test_file.json", ifstream::in);
cout << "we have opened json inFileJSON" << endl; // get here
inFileJSON >> baseJObject;
cout << " Can direct inFileJSON into baseJObject" << endl; //never get here; the app aborts.
inFileJSON.close();
return baseJObject;
}
This seems basically identical to the example on the nlohmann site:
// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;
I just expected this to open the json file, load it into the object, and return the object. Instead, it just quits.
Thanks for any thoughts...i.e., what am I doing wrong? (I'm going to ignore that it worked before...maybe I missed something).
--Al
As requested, here is a minimal reproducible example, but it will require nlohmann's json.hpp in order to compile:
#include <iostream>
#include <fstream>
#include "json.hpp"
using json = nlohmann::json;
using namespace std;
string fileName;
json baselineOpenAndRead(string);
int main(int argC, char *argV[])
{
json baseJObject;
if (argC != 2) // check to make sure proper number of arguments are given.
{
cout << "\n\nFilename needed...";
exit(1); // number of arguments is wrong - exit program
}
else
{
fileName = argV[1];
baseJObject = baselineOpenAndRead(fileName); // opens and reads the Base Line JSON file
cout << "baseJObject returned" << endl;
}
return 0;
}
json baselineOpenAndRead(string fileName) //
{
cout << "File name: " << fileName << endl;
json baseJObject;
cout << "we have a baseJObject" << endl;
ifstream inFileJSON(fileName);
if (inFileJSON.is_open())
{
cout << "file open..." << endl;
if (nlohmann::json::accept(inFileJSON))
{
cout << "valid json" << endl;
try { inFileJSON >> baseJObject; }
catch (const std::exception &e) { std::cout << e.what() << '\n'; throw; }
}
else
{
cout << "not valid json" << endl;
}
}
else
{
cout << "file not really open" << endl;
}
inFileJSON >> baseJObject;
cout << " We can echo inFileJSON into baseJObject" << endl;
inFileJSON.close();
return baseJObject;
}
I tested it with this json file:
{
"people": [{
"name": "Scott",
"website": "stackabuse.com",
"from": "Nebraska"
},
{
"name": "Larry",
"website": "google.com",
"from": "Michigan"
},
{
"name": "Tim",
"website": "apple.com",
"from": "Alabama"
}
]
}
When I run this passing it the json above as data.json, I get the following output and then it quits:
./Test_json data.json
File name: data.json
we have a baseJObject
file open...
valid json
[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
Without the try, it just quits. It never gets past inFileJSON >> baseJObject;
Another try that seems to work, but why?
OK. I tried this with the same main (the only changes are in the function):
json baselineOpenAndRead(string fileName) //
{
json baseJObject;
string filePath = "../baselines/" + fileName;
cout << "filePath: " << filePath << endl;
ifstream inFileJSON(fileName);
//baseJObject = json::parse(inFileJSON);
inFileJSON >> baseJObject;
cout << baseJObject << std::endl;
return baseJObject;
}
This looks basically the same to me. I tried making it ifstream inFileJSON(fileName.c_str()) on both the original and in this one. The original continued to fail, this one continued to work. Sorry this is getting so long, but I can't get decent formatting out of comments... Should I just try answering my own question instead?
I think I've got this. I believe my initial problem was caused by an errant ',' in one of my json test files. Subsequently, the if (inFileJSON.is_open) worked, but the if (nlohmann::json::accept(inFileJSON) was failing and causing the same (or perhaps a similar) error. I thought that I needed the c_str() for file paths outside of the executable's directory, but it doesn't seem to make a difference one way or the other. I took out the accept(), and this code seems to work consistently:
json baselineOpenAndRead(string fileName) //
{
json baseJObject;
cout << "we have a baseJObject" << endl;
string filePath = "../baselines/" + fileName;
cout << "filePath: " << filePath << endl;
//ifstream inFileJSON(filePath.c_str());
ifstream inFileJSON(filePath);
if (inFileJSON.is_open())
{
cout << "File is open." << endl;
inFileJSON >> baseJObject;
cout << baseJObject << std::endl;
inFileJSON.close();
return baseJObject;
}
else
{
cout << "File not open." << endl;
exit(1);
}
}
Thanks to everyone for your help. I appreciate it.
--Al
I'm using visual studio 2017, running with the c++17 ISO Standard(not boost) set to be able to use <filesystem>. I'm running into a wall though because everytime I run, whether in debug or release, file_copy() gives me the error access denied. I've checked the other bits of my code and the only thing that isn't working is file_copy(). Does anyone know why I'm getting this error and how to fix it? I'm the administrative account on my PC.
std::vector<std::string> findAndCopyFiles()
{
std::vector<std::string> fileNames;
std::error_code errCode;
errCode.clear();
fs::current_path("C:\\Users\\kenny\\Desktop\\Engine", errCode);
std::cout << errCode.message() << std::endl; errCode.clear();
fs::path pa = fs::current_path();
pa += "\\TEMP";
std::cout << pa.string() << std::endl;
if (fs::create_directory(pa, errCode))//Create directory for copying all files)
{
std::cout << "Directory created successfully" << std::endl;
std::cout << errCode.message() << std::endl; errCode.clear();
}
fs::path tempDir(pa);
fs::path currentDirectory = fs::current_path();
fs::recursive_directory_iterator dirIter(currentDirectory);
for (auto &p : dirIter)
{
if (p.path().extension() == ".cpp" || p.path().extension() == ".h")
{
//std::string fileContents = getFileContents(p.path().string());
std::string fileName = p.path().stem().string();
if (!fs::copy_file(p.path(), tempDir, fs::copy_options::overwrite_existing, errCode))
{
std::cout << "failed to copy file: " << fileName << " from " << p.path().string() << " to " << tempDir.string() <<std::endl;
}
std::cout << errCode.message() << std::endl; errCode.clear();
//ensures file is a cpp file before adding it to list of fileNames
if (p.path().extension().string() == ".cpp")
{
auto it = std::find(fileNames.begin(), fileNames.end(), fileName); //seaches TEMP folder for file
if (it == fileNames.end())
{//if file was not found in vector of registered file names, add it
fileNames.push_back(fileName);
}
}
}
}
std::cout << "All files found. " << fileNames.size() << " files were found" << std::endl;
return fileNames;
}
As per the comments. You were trying to overwrite a directory with a regular file. From the documentation [trimmed]
o Otherwise, if the destination file already exists...
o Report an error if any of the following is true:
o to and from are the same as determined by equivalent(from, to);
o to is not a regular file as determined by !is_regular_file(to)
So you need to append the filename to the destination directory path using the `std::filesystem::operator/ overload (untested)...
if (!fs::copy_file(p.path(), tempDir / p.filename(), fs::copy_options::overwrite_existing, errCode))
I have a JSP to upload a file which works fine. After the file has been uploaded I am trying to open the file again using the file path saved from the form data.
However, the filepath variable shows fine but the ifstream fails. If the csvFileName variable is set manually to path + file name it works fine. Doing this on a MAC and trying to avoid using boost library.
form_iterator two = cgi.getElement("csvFileName");
csvFileName=two->getValue();
form_iterator three = cgi.getElement("csvFilePath");
filePath = three->getValue();
csvFileName.c_str();
ifstream thefile;
thefile.open(csvFileName);
cout << "Filename is: " << csvFileName << endl;
if (thefile.is_open())
{
cout << "<H1>It's working</H1>" << endl;
while ( getline (thefile,line) )
{
cout << line << '\n';
}
thefile.close();
}
else
{
cout << strerror(errno) << endl;
}
IN IOS app, module written in C++ I am writing my data (map of basic strings and integers) to a text file. Using following method:
bool Recognizer::saveMap(const char * s)
{
if(trainingData.model && !trainingData.model.empty()) {
const string filename = string(s);
std::ofstream file(s, ios_base::trunc );
try{
if(! file.is_open())
{
file.open(s);
}
for (map<String,int>::iterator it=trainingData.idMap.begin(); it!=trainingData.idMap.end(); ++it)
{
cout << it->second << " " << it->first << endl;
file << it->first << endl << it->second << endl;
}
file.close();
}
catch(cv::Exception & e){
if(file.is_open())
file.close();
int code = e.code;
string message = e.err;
cerr << "cv::Exeption code: " << code << " " << message << endl;
return false;
}
std::streampos fileLength = iosFileSize(s);
cout << "Saved map to: " << filename << " length: " << fileLength << endl;
return true;
}
return false;
}
My contains one entry and console output indicates that two lines: string, string representing number have been written to my file.
Subsequent opening file for reading and reading using getline or using stream operator indicates that file is empty:
bool Recognizer::loadMap(const char * s)
{
std::streampos fileLenght = iosFileSize(s);
std::ifstream file(s, ios::in);
try{
if(file.is_open())
{
string name;
string lineName;
string lineTag;
int tag;
int count = 0;
while(getline(file,name))
{
if(getline(file,lineTag))
{
tag = stoi(lineTag,0,10);
count++;
cout << tag << " " << name << endl;
trainingData.idMap[name]=tag;
trainingData.namesMap[tag]=name;
}
}trainingData.personsCount=count;
file.close();
}
}
catch(cv::Exception & e){
if(file.is_open())
file.close();
int code = e.code;
string message = e.err;
cerr << "cv::Exeption code: " << code << " " << message << endl;
return false;
}
cout << "Loaded map from: " << s << " lenght: "<< fileLenght << endl;
return true;
}
I also copied from one of stackoverflow answers method returning file lenght and using it to verify lenghth of the file after write operation:
std::streampos iosFileSize( const char* filePath ){
std::streampos fsize = 0;
std::ifstream file( filePath, std::ios::binary );
fsize = file.tellg();
file.seekg( 0, std::ios::end );
fsize = file.tellg() - fsize;
file.close();
return fsize;
}
The file path passed to saveMap and loadMap seems to be legit. With path that the app could not write to, attempt to write caused exception.
There are no errors returned by write operation but both, attempts to read and iosFileSize() indicate that file is empty.
I am not sure if i need call file.open() and file.close() or file is open and closed automatically when output stream is created and later goes out of scope.
I experimented with those with the same result ( call to file.is_open returns true so the block calling file.open() is skipped.
What am I doing wrong?
I appreciate all responses.
It does not seem like you call file.flush(); anywhere in Recognizer::saveMap() after writing to the file stream. std::ofstream::flush() saves changes you've made to the file. Add file.flush(); between when you make changes to the code and when you close the file. See if that remedies your issue.
I also had the same issue. Using file.flush() everytime after you insert to a file can save your file.
However if you insert something like this, say,
file << "Insert This"; You will need to add file.flush().
But some people have issues, like if you just insert file << "Insert This" << endl; , this works fine. The key point here is that, std::endl calls flush() everytime it is used internally. you can say it is a shortend form of "\n" + flush().
I believe from looking at your code that you are overwriting your data when you open the file in the second program you should be using something like this.
std::fstream fs;
fs.open ("test.txt", ios::app)
instead of doing the ios::in