ofstream wont create files in documents folder - c++

I'm trying to make a function for a game I'm making that saves data from the game to a text file in a folder, both with a name provided by the user. I was able to do this in my project folder, and wanted it to be in a more universal place, so I am trying the documents folder.
When I switched the locations, however, the code stopped producing the desired result, and started creating the file and the folder in my program's main directory. (the file is not in the folder, fyi)
void Player::save()
{
system("mkdir \"C:\\Users\\Default\\Documents\\Ice Road\"");
//Make "Ice Road" folder in documents
std::string filename((name + ".txt"));
//make a name (inputed by the user earlier) to later be used to name a text file
std::string command("mkdir ");
//string to be combined with name to make folder
std::string commandString((command + name));
//combine to make string command that creates folder
std::string newDir = ("C:\\Users\\Default\\Documents\\Ice Road\\" + name);
//string to set directory to newly created folder
std::ofstream saveStream;
//open output stream for the saving process
SetCurrentDirectory("C:\\Users\\Default\\Documents\\Ice Road\\");
//set the directory to the Ice Road documents folder (DOES NOT WORK)
system((commandString.c_str()));
//create named folder for the save files.
SetCurrentDirectory(newDir.c_str());
//set the directory to the newly created folder
saveStream.open(filename.c_str());
//Create/open a text file that holds the data being saved
system("echo on");
//turn on echo for debugging
saveStream << name << std::endl
<< difficulty << std::endl
<< health << std::endl
<< warmth << std::endl
<< hunger << std::endl
<< packSpace << std::endl
<< packUsed << std::endl;
saveStream.close();
//input data to save file
system("dir");
//show folder for debugging
system("PAUSE");
//wait for input
}
How could I get this code to create a folder in documents called Ice Road, with the named folder inside and the named text file inside that?
(Documents\Ice Road\yourname\yourname.txt)

I solved the problem. My biggest problem was that I had no access to this folder (UAC), but because I wasn't receiving any errors I didn't think of it. Between that and some other tweaking I got it to work as shown below, running as administrator.
void Player::save()
{
std::string iceroad("C:\\Users\\Default\\Documents\\Ice Road");
//Ice road directory, made into a string variable for easy usage, as recommended by Ben
system("mkdir \"C:\\Users\\Default\\Documents\\Ice Road\"");
//Make Ice Road folder in documents
std::string filename(iceroad + "\\" + name + "\\" + name + ".txt");
//make a name (inputed by the user earlier) to later be used to name a text file, now using full address
std::string command("mkdir ");
//string to be combined with name to make folder
std::string commandString((command + name));
//combine to make string command that creates folder
std::string newDir = (iceroad + "\\" + name);
//string to set directory to newly created folder, simplified
std::cout << filename;
//debugging, as reccommended by Dietmar
std::ofstream saveStream;
//open output stream for the saving process
SetCurrentDirectory(iceroad.c_str());
//set the directory to the Ice Road documents folder
system("dir");
//debugging, as recommended by Dietmar
system((commandString.c_str()));
//create named folder for the save files.
SetCurrentDirectory(newDir.c_str());
//set the directory to the newly created folder
saveStream.open(filename.c_str());
//Create/open a text file that holds the data being saved
system("echo on");
//turn on echo for debugging
saveStream << name << std::endl
<< difficulty << std::endl
<< health << std::endl
<< warmth << std::endl
<< hunger << std::endl
<< packSpace << std::endl
<< packUsed << std::endl;
saveStream.close();
//inputs data to save file
system("dir");
//show folder for debugging
system("PAUSE");
//wait for input
}
Thank you for your constructive critiques, I did take them to heart and implement them.

Related

Always empty metadata

I'm writing audio player using QtMutimedia, and need got audio file metadata.
I'm using this code, but always returns empty strings on every file. How fix this?
Qt 5.15.2 MinGw
QStringList meta = player->availableMetaData();
qDebug() << "File meta: ";
foreach(QString data, meta){
qDebug() << data;
}

QT Creator - Parsing through CSV file

OK, so I am using QT Creator for C++ and I am making a function that allows me to parse through the CSV file that I have named getExcelFile. Everything else is working fine but my code will not enter my while loop for some reason which is driving me crazy. Some suggestions would be helpful! Thanks.
void Widget::getExcelFile(){
//Name of the Qfile object.
//filename is the directory of the file once it has been selected in prompt
QFile thefile(filename);
//If the file isn't successfully open
if (thefile.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "File opened successfully";
//Converts text file to stream
QTextStream in(&thefile);
fileContent=in.readAll();
QString line;
while (!in.atEnd()){
//line = textStream.readLine();//reads line from file
//Will not enter this loop for some odd reason.
qDebug() << "This text does not print out";
}
}
qDebug() << "This prints out successfully";
ui->textEdit->setPlainText(fileContent);
}
You did in.readAll(), after that call in.atEnd() will return true. Either remove in.readlAll() or while loop, why do you need both?

Duplicate events received from POCO DirectoryWatcher

I'm trying to use the DirectoryWatcher class from POCO's file system library to monitor a specific folder for changes. The code is pretty simple and looks like this:
Monitor::Monitor() {
pattern = new Glob("/path/to/dir/*.dat",
Glob::GLOB_DOT_SPECIAL);
watcher = new DirectoryWatcher(std::string("/path/to/dir"));
watcher->itemAdded += delegate(this, &Monitor::onFileAdded);
watcher->itemModified += delegate(this, &Monitor::onFileChanged);
}
void Monitor::onFileAdded(const DirectoryWatcher::DirectoryEvent& addEvent) {
if (pattern->match(addEvent.item.path())) {
std::cout << "File added: " << addEvent.item.path() << std::endl;
}
}
void Monitor::onFileChanged(const DirectoryWatcher::DirectoryEvent& changeEvent) {
if (pattern->match(changeEvent.item.path())) {
std::cout << "File changed: " << changeEvent.item.path() << std::endl;
}
}
I'm observing some odd behavior. If I copy a new version of a file over a file that's already in the watched folder, I receive the 'item changed' notification twice. If I open a file that's already in the watched folder, edit its contents and save it, I receive an 'item added' notification followed by an 'item changed' notification.
This is on Ubuntu Linux 14.04 and ext4 file system with POCO 1.4.6p2.
Has anyone else observed similar behavior? Could this be related to some specific characteristic of my machine and the OS/file system combo? Is it possible to filter the unwanted events somehow?
Thanks in advance.

Can't extract exe or dll files with quazip (Qt)

I am building a qt framework to download and install application updates (like sparkle for obj-c). The download works, the downloaded zip file is valid and i can extract the contents manually but when I let my framework unzip the contents via quazip the files (dll and exe) contains this and only this string: "MZ" and a special char which is wrong encoded (some kind of square on windows and "ê" on mac), so exactly 3 bytes. When I include a text file (or xml) in the zip file, it will be unzipped correctly, manually and with quazip, so I assume that the library was compiled correctly. Where is my error?
I think this can be part of the solution http://en.wikipedia.org/wiki/DOS_MZ_executable?
Here is my method to install the update:
QuaZip archiveWrapper(filename); // The downloaded zip file
if (archiveWrapper.open(QuaZip::mdUnzip)) {
QuaZipFile archive(&archiveWrapper);
qDebug() << "Extracting files" << archiveWrapper.getFileNameList();
for (bool more = archiveWrapper.goToFirstFile(); more; more = archiveWrapper.goToNextFile()) {
QString filePath = archiveWrapper.getCurrentFileName();
QString destinationPath = QDir::cleanPath(QDir::currentPath() + QDir::separator() + filePath);
QString destinationBackup = destinationPath + "_backup";
qDebug() << "Extract" << filePath << "to" << destinationPath;
QuaZipFile zip(archive.getZipName(), filePath);
zip.open(QIODevice::ReadOnly);
QByteArray data = zip.readAll();
zip.close();
QFile oldFile(destinationPath);
if (oldFile.exists()) {
qDebug() << "Rename" << destinationPath << "to" << destinationBackup;
if (!oldFile.rename(destinationBackup)) {
qWarning("Could not rename %s to %s!", destinationPath.toUtf8().constData(), destinationBackup.toUtf8().constData());
}
}
QFile destination(destinationPath);
destination.open(QIODevice::WriteOnly);
destination.write(data.data());
destination.close();
if (oldFile.exists()) {
qDebug() << "Deleting backup of" << destinationPath;
if (!oldFile.remove()) {
qWarning("Could not delete %s!", destinationPath.toUtf8().constData());
}
}
}
if (archive.getZipError() == UNZ_OK) {
qDebug() << "All files extracted successfully";
qDebug() << "Restarting application...";
archiveWrapper.close();
qApp->quit();
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
} else {
qWarning("Error while extracting files (Error %d)", archive.getZipError());
archiveWrapper.close();
}
} else {
qWarning("Could not open archive to extract contents");
}
Edit:
I found out that data (QByteArray) has the expected size, so I think the problem is that QFile does not write the contents of QByteArray into the exe/dll files the way it should be?
Edit 2:
I've found one error, the file size to write:
destination.write(data.data(), data.size());
instead of
destination.write(data.data());
but still, the exe does not have an icon or is executable (but with the correct file size). For a short time a dos window opens and closes. There is a antivirus software running but there is no alert (and because this is a corporate notebook i am not able to shut it down and the update framework should also be running whether there is a antivirus software running or not).
Edit 3:
Although I thought writing exe files is complicated, it was a mixture of stupid bugs I "implemented" for testing purposes. So the simple
QFile destination(destinationPath);
destination.open(QIODevice::WriteOnly);
destination.write(data.data(), data.size())
is sufficient.

File retrieving in MongoDB using C++ Drivers

I am doing one project to make a database application in which i need to store some files in the database and later i need to retrieve those files back to the local system. I am using C++ drivers of the mongoDB..Storing the files on the server is working perfectly and when i am trying to retrieve it back only text files are received as it is but when i am doing it with images, .pdf files or other files format the file is corrupt.Can anyone tell me how i can save the files on local system without any corruption. Thanks
Code:
std::fstream out;
const char* gridfilename="Penguins.jpg";
const char* filename="Temp.jpg";
out.open(filename, ios::out);
DBClientConnection c;
c.connect("localhost");
cout << "connected ok" <<endl;
GridFS gfs = GridFS(c, "Test", "DB");
GridFile gf = gfs.findFile(gridfilename);
if (true != gf.exists()) {
cerr << "There is no file like " << gridfilename << endl;
}
gf.write(out);
out.close();