How to open a separate program with C++ / OS X - c++

How can I open a program (.exe or .app) using my C++ program?
Like iTunes, Safari, Pages.
For example;
If I wanted to manually write into a "example.txt", "example.docx" or "example.pages" file, how could I get that file to open the TextEdit, M Word or Pages programs/applications rather than write from inside the Terminal.
I'm not talking about fstream, as thats all I can find on the topic. I feel I've got that pretty down packed (basic example code below)
cout << "Enter File Name:\n" << endl;
cin >> fileName;
char a;
cin.get(a);
outStream.open(fileName.c_str());
cout << "\nWhat would you like to write?\n" << endl;
getline(cin, fileWrite);
cout << "\nWriting to " << fileName << endl;
outStream << fileWrite;
outStream.close();
While I want my program to be able to Read/Write in streams, I want to also be able to add an option of having the ACTUAL document open so you can MANUALLY Read or Write into it along with the programs edit features and whatnot without using the "system()" command (as I've read that it has too many risks depending on what you're choosing to open)

The correct approach to opening documents, URLs, or applications on OS X is to use the Launch Services API. (If you were using Cocoa, you would use NSWorkspace, which is built on top of Launch Services.) In particular, you can call LSOpenCFURLRef().

Related

Writing to files safely in c++

Let's say you have a txt file, it currently holds content that's important. Currently the content is at such
"I like blue cats and yellow dogs."
but you want to update said content.
std::ofstream myFile;
myFile.open("file.txt");
myFile << "I like " << catColorStr << " cats and " << dogColorStr << " dogs.";
myFile.close();
But let's say for some reason your program crashes between line two and three or maybe the user's power cuts out or they use end process in windows task manager etc. Well you have just deleted the entire contents of file.txt. How do you go about accounting for this typically?
Is the typical way of dealing with this to open it as read only copy the contents to your program. Then copy that to a new tempfile or something. Then write to your actual file and if that succeeds deleting your tempfile else upon start you say your actual file = your temp file?
Typically, you create a new file, write to it, close it, then rename the new file to the old file.
std::ofstream myFile;
myFile.open("file.txt.new");
myFile << "I like " << catColorStr << " cats and " << dogColorStr << " dogs.";
myFile.close();
sys::filesystem::rename("file.txt.new", "file.txt");
// or POSIX rename or Windows or...
(Error checking omitted for brevity)
The rename operation atomically deletes the old file and gives the new file the old name. If somebody pulls the power cord in the middle of it, it's your operating system's problem, not yours. Modern OSes are quite good at dealing with it.

How to make a C++ program that works with a .txt file without showing it

My program needs to use a hidden text file to keep track of user's name.
But when the program starts, if it can't find the 'Name.txt' file in the same directory, it generates one that is visible to the user.
The user can view it, edit it, and so on. How can I prevent this from happening, so that only my program can modify the file?
Also, is there a better way to keep knowledge of the name of the user (keep in mind I'm new to programming in general, not only to C++)?
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <string>
#include <Windows.h>
using std::string;
using std::cout;
using std::cin;
using std::ifstream;
using std::ofstream;
int main()
{
string line;
ifstream example;
example.open("Name.txt");
getline(example, line);
if (line.compare("") == 0)
{
example.close();
string con;
cout << "Welcome to this program!\n";
cout << "Do you want to register? (y/n) ";
cin >> con;
con[0] = tolower(con[0]);
if (con.compare("n") != 0)
{
string name;
ofstream one;
one.open("Name.txt");
cout << "What's your name? ";
cin >> name;
one << name;
one.close();
cout << "See you later " << name << ".";
Sleep(4000);
}
}
else
{
cout << "Welcome back " << line << ".";
example.close();
Sleep(4000);
}
}
EDIT : I just realised I said 'to keep track of the user'. Now I realized why you guys thought I wanted to do something bad with this program. I corrected it now, what I meant was 'to keep track of the user’s name'.
I understand that you want to maintain a file that contains the names of all the registered users, or some other kind of current-user-independent data.
The problem
Your code tries to open the file in the current working directory of the program. Unfortunately, it depends on the way the user has launched your program.
It also ignores possible errors during the opening when reading the file. So if the file isn't there, your code will open the file as ofstream for writing (which will create the file if it doesn't exist).
How to solve it ?
To fulfill your requirements, you should open the file in a predetermined location (for example fixed during the installation process, or in the program's configuration). See this article, on where to ideally store data and configuration files on windows platform.
If you want to make sure that the program only opens the file if it already exists, you should verify the result of the open on the ifstream and issue an error message if this failed:
example.open("Name.txt");
if (!example) {
cout << "OUCH ! Fatal error: the registration file couldn't be opened !" <<endl;
exit (1);
}
How to protect the file against users ?
Note however that if your program reads and writes data from the file, the user could find it also and edit it manually. This will be difficult to prevent.
Alternatively you could consider using the windows registry, which is less trivial for the user to edit (although not impossible). The major inconvenience of this approach is that it's system dependent and it will make the porting of your code to other platforms much more difficult.
If you want to fully protect your file, you could as suggested by Chris in the comment, encrypt the file. Encryption is complex business; Consider using a library such as openssl or a proven algorithm.
This will protect you against ordinary users. But you'd still be exposed to hackers able to reverse engineer your code and to find the encryption key that must be somehow embedded in your code to decrypt the file.

C++ ignoring cout redirect for some outputs

I'm launching my program using the command line and the redirect symbol like so
program > out.txt
Is there a way some cout calls can ignore the > operator and still be displayed in the console?
What I want is to have a console menu that will appear in the console, but the rest will get redirected to the file.
Thank you.
No, there isn't.
> redirects the whole stdout stream to a file, not particular writes to that stream. If you want to write to multiple locations, you are to use multiple streams. For example, you could use stderr:
cout << "redirected" << endl;
cerr << "not redirected" << endl;
You could reformat what you are doing and use std::cout when you want to go to stdout, and a Log function that writes to a file you specify as the input to the progam.
It might be neater still to have a Menu function which displays to std::cout, and the Log file able to be configured as to where it ends up.

Program opens file but is unable to write nor read from it

I was unable to access files in a program and drafted (mostly copied and pasted) a segment for testing doing so- just to troubleshoot.
fstream file;
file.open("thishere.txt");
if(file.is_open())
{
cout << "Managed to open file" << endl;
file << "Here's some info for muh file\n";
cout << "Attempted to give info to file, read: " << endl;
string line;
while ( getline (file,line) )
{
cout << line << '\n';
}
} else cout << "Failed to open file" << endl;
The program returns Managed to open file \n Attempted to give info to file, read: and stops there. There is text already in the file to read off of and it does not return anything. Also nothing new appears on the file.
So it manages to neither write down information on the file, nor read information from the file, even though it is supposedly open. When I delete the file from the directory my program says Failed to open file. I've heard of IDE's using the wrong directory so I manually used the EXE in the directory I wanted and got the same results. I have permissions to the file, and am running the EXE as administrator.
What am I missing?
I'm using Windows 8 if that's pertinent
EDIT:
I solved my own problem if anyone cares, it was only half the code. There was no file.close() so the file did not save. Kenny Orstroms answer also solved my problem of no text appearing. All good now!

C++ - ofstream doesn't output to file until I close the program

I have the following code:
ofstream mOutFile.open(logPath, ios_base::app);
string lBuilder;
lBuilder.append("========================================================\n");
lBuilder.append("Date: ");
lBuilder.append(asctime(timeinfo));
lBuilder.append("\n");
lBuilder.append("Log Message:\n");
lBuilder.append(toLog);
lBuilder.append("\n");
lBuilder.append("========================================================\n\n");
int lSize = lBuilder.size();
char* lBuffer = new char[lSize];
int index = 0;
for each (char c in lBuilder)
lBuffer[index++] = c;
mOutFile.write(lBuffer, lSize);
mOutFile.flush();
Unfortunately, until I close the app (I assume that closing the ofstream would work as well) the output does not get written to the text file. I know I could probably close and reopen the stream and everything will "just work" but that seems like a silly and incorrect solution. What am I doing wrong here?
I have also tried the following variations based on other questions I have found here, but these solutions did not work:
mOutputFile << flush;
mOutputFile << endl;
Thanks in advance for any assistance on this.
edit Everything in this code is working visual c++, it builds and works fine except the file is not written to until the stream is closed, even if I force a flush. Also, I switched from using the << operator to the char * and .write () to see if anything behaved differently.
std::ofstream file(logPath, ios_base::app);
file << "========================================================\n"
<< "Date: " << asctime(timeinfo)
<< "\nLog Message:\n" << toLog
<< "\n========================================================\n\n"
<< std::flush;
//if you want to force it write to the file it will also flush when the the file object is destroyed
//file will close itself
This is not only easier to read but it will probably also be faster than your method + it is a more standard appraoch
I ended up just "making it work" by closing and reopening the stream after the write operation.
mOutputFile << "all of my text" << endl;
mOutputFile.close();
mOutputFile.open(mLogPath);
EDIT After trying out forcing the flush on a few other systems, it looks like something just isn't performing correctly on my development machine. Not good news but at least the above solution seems to work when programmatically flushing the ofstream fails. I am not sure of the implications of the above code though, so if anyone wants to chime in if there are implications of closing and reopening the stream like this.
You can perform the following steps to validate some assumptions:
1.) After flush(), the changes to the file should be visible to your application. Open the file as std::fstream instead of std::ofstream. After flushing, reset the file pointer to the beginning and read the contents of the file. Your newly written record should be there. If not, you probably have a memory corruption somewhere in your code.
2.) Open the same file in an std::ifstream after your call to flush(). Then read the contents of the file. Your newly written record should be there. If not, then there's probably another process interfering with your file.
If both works, then you may want to read up on "file locking" and "inter-process syncronization". The OS can (theoretically) take as much time as it wants to make file changes visible to other processes.