PDA

View Full Version : Problem reading from input file in simple console application




Tommas
Aug 4, 2013, 12:47 PM
Hello! I am attempting to write a simple console application that reads from a text file and then generates a random sentence based on the rules/words in the text file. The program works just fine on my windows machine, and, because I didn't include a file path for the input file, it just looks for it in what ever folder the application is in, which makes it really easy to move to a different computer (where the file path would be different) to show someone else. However, when I tried to recompile it on my mac, in Xcode, the application can't read the text file, even though I put the text file in the folder with the application (in the DerivedData/ProgramName/Build/Products/Debug folder). If I just run the program in Xcode the program reads the data file just fine, but the standalone application can't. Any ideas?

Relevant portion of my program:

vector<string> s;

ifstream data;
data.open("default.txt");


if(!data)
{
cerr << "Could not open input file.\n";
consolePause();
exit(1);
}

string line;
while (getline(data, line))
{
s.push_back(line);
}

data.close();


Thanks for your help!



chown33
Aug 4, 2013, 02:25 PM
A crucial part of debugging is confirming expected results with actual results.

We know what you expect the working directory (http://en.wikipedia.org/wiki/Working_directory) to be, because you wrote:
... it just looks for it in what ever folder the application is in, ...
So you're apparently expecting the working directory to be the same directory where the application itself resides.


To discover the actual working directory, see the C function getcwd():
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/getcwd.3.html

Also see:
http://stackoverflow.com/questions/2203159/is-there-a-c-equivalent-to-getcwd

Found by googling: getcwd c++


After you know the exact cause of the problem, you can work on creating a solution. But without knowing or understanding the cause, you can't create a solution.

Tommas
Aug 4, 2013, 03:19 PM
Thank you for the help! I am fairly new to this, so any advice is appreciated. I will try that command when I get home to double check that I have the working directory correct.

For now though, do you know a way to cause the program to search for the file in the folder it is currently located in? For example, say I had the program and the input file in a folder called MyProgram in my documents folder. I would want the program to find the input file in the MyPrograms folder, even if I then moved the MyProgram folder to the desktop, or to my friends computer. Does that make sense? Is it doable? Thanks, again!

chown33
Aug 4, 2013, 03:43 PM
Which versions of OS X does your program need to run on? Be sure to include your OS version as well as that of whoever you will be sending the program to.


Which version of Xcode are you using to develop and debug the program?


How is the program actually started? Is it a command line in Terminal? A bundled app? Be specific.

Tommas
Aug 4, 2013, 03:53 PM
My Mac is running 10.7, and I hope to be able to share it with people who own macs that run 10.7 and 10.8.

I just updated my Xcode to the most recent free version, 4.6, I believe.

chown33
Aug 4, 2013, 10:06 PM
Please answer the 3rd question:
How is the program actually started? Is it a command line in Terminal? A bundled app? Be specific.




For getting the directory that the program resides in, take a look at the CFBundle (https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFBundleRef/Reference/reference.html%23//apple_ref/doc/uid/20001191) type. Specifically, get the main bundle, then use one of the functions that returns a pathname within the bundle.
CFBundleGetMainBundle
Returns an application’s main bundle.

CFBundleRef CFBundleGetMainBundle (
void
);
Return Value
A CFBundle object representing the application’s main bundle, or NULL if it is not possible to create a bundle. Ownership follows the Get Rule in Memory Management Programming Guide for Core Foundation.

Discussion
CFBundle creates a main bundle whenever it possibly can, even for unbundled apps. There are a few situations in which it is not possible, so you should check the return value against NULL, but this happens only in exceptional circumstances.
[emphasis added]


You'll also want to read the Bundle Programming Guide doc (see left-hand column in CFBundle class reference doc).

If you want the Objective-C equivalen, see the NSBundle class, the mainBundle and bundlePath methods. You can wrap that into a C++ function, put it in a ".mm" source file, and it will be automatically compiled as Objective-C++.

Finally, I recommend writing some test cases to learn exactly how things behave.

Tommas
Aug 5, 2013, 08:12 AM
Thank you so much for your help! I will try that. I'm really glad experiences programmers, like you, take the time to help those of us just starting out.

Sorry, I missed the third question: I'm hoping that the program will be able to be opened by double clicking it.

chown33
Aug 5, 2013, 10:36 AM
Sorry, I missed the third question: I'm hoping that the program will be able to be opened by double clicking it.

Have you tested that it launches that way?

Hoping is no substitute for testing.

Tommas
Aug 5, 2013, 04:49 PM
The program indeed does open by double clicking it.

I finally figured out how to use the getcwd function, and you were completely right- it is looking for the text file in the /Users/MyName folder, instead of in the folder the application resides in. When I run the program from within Xcode, the program's working directory is where I assumed, which is why the program works in Xcode, but not when opened as a stand-alone app.

Now that I know that, I am going to delve into CFBundle and see if I can't convince the program to look for the text file in whatever folder the application is in. Thank you for the suggestions, and advice!