C++ Program Can't Locate Input Files

Discussion in 'Mac Programming' started by Central Limit, Jul 24, 2011.

  1. Central Limit macrumors newbie

    Joined:
    Jul 24, 2011
    #1
    I'm new to programming on a mac.

    I've just finished a C++ program using Xcode. It opens an input file, reads the contents, then opens an output file and writes the results there. It works fine when I run it from Xcode. But, when I move the executable file to my desktop, and I move my input file to my desktop, it doesn't work. The program can't find the input file even though the executable and the input file are both on the desktop.

    Can someone explain why this is happening and the simplest way to fix it?

    Thank you.
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
  3. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #3
    Post your code.

    Post any error messages your program emits.

    Post the exact command-line used to run your code.
     
  4. Central Limit, Jul 24, 2011
    Last edited by a moderator: Jul 24, 2011

    Central Limit thread starter macrumors newbie

    Joined:
    Jul 24, 2011
    #4
    Here is the code.

    PHP:
    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    #include <strstream>
    #include <string>
     
    int main (int argcchar * const argv[]) {
        
        
    std::cout << "Program Running\n";
        
    char initarray[99];    // the initial message
        
    char jibarray[99];  // encoded message.  jibberish
        
    char decarray[99];  // decoded message.  should match initial

        
    int i;
        
        
    char mode;
        
    std::cout << "Encoding or Decoding?  Enter 'e' or 'd'\n";
        
    std::cin >> mode;
        
        
        
    char xyz[99];
        
    std::cout << "Enter Password\n";
        
    std::cin >> xyz;
        
    int plen strlen(xyz);
        
    std::ifstream infile;
        
    std::ofstream outfile;


        if (
    mode == 'e')
        {
            
    //infile.open("/Users/studentmac/Desktop/initial.txt");    
            
    infile.open("initial.txt");    
            
    outfile.open("jibberish.txt");
            
    int n 0;
            while(
    infile >> initarray[n])
            {
                ++
    n;
            }
            for (
    0ni++)
                
    std::cout << initarray[i];
            
    std::cout << "\n";    
            
    std::cout << "message length: " << << "\n";
            
    std::cout<< "encrypted message: " << "\n";
            for (
    0i<ni++)
            {
                
    int imod i%plen;
                
    jibarray[i] = initarray[i] + xyz[imod];    
                
    outfile << jibarray[i];
                
    std::cout<< jibarray[i];
            }
            
    outfile << "\n\n";
            
    std::cout<<"\n";
            
    infile.close();
            
    outfile.close();
            
            
        }
    In XCode, when I go to the "run" menu, the program works fine.

    But, if I copy the executable file to my desktop and copy my input file to my desktop, and then double click the executable, the program runs, but fails to find the input file.

    This line of code:

    PHP:
    std::cout << "message length: " << << "\n";
    prints out 0. Also, the desired output file, jibberish.txt does not get created as it should.


    As I said, I am new to programming on a mac.
     
  5. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #5
    Your posted code presumes that it will always be launched with the current working directory set to its own directory. This is not necessarily true. Other platforms may do that, or they may not. Mac OS X does not.

    In particular, double-click does not set the working directory to the location of the executable.

    You can confirm your assumption using the getcwd() C function.

    When you discover what the working directory actually is, look at its permissions using the 'ls' command, and you will see why your program can't create its output file. The command would be:
    Code:
    ls -ld /path/to/workingDir/here
    
    If you were to run Terminal.app and go to your Desktop folder using the 'cd' command, then run your program, you should find the working directory is set to the location of the executable. But that's only true because 'cd' is the command that changes the working directory. Otherwise it's still false.

    For example, if you ran your program like this in Terminal (without cd'ing first):
    Code:
    Desktop/yourProgramNameHere
    
    it would run, but fail to find the input file.
     
  6. Central Limit thread starter macrumors newbie

    Joined:
    Jul 24, 2011
    #6
    Excellent! That is certainly the problem. But I don't think your post explains how to fix the problem. Does it?
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    Your posted code included this line:
    Code:
    //infile.open("/Users/studentmac/Desktop/initial.txt");    
    
    so I assumed you knew how to fix the problem. If you have a file located at a specific absolute path, then use the absolute path. Same applies to the output file.

    Perhaps you meant to ask "How can my program identify its parent directory when launched?". The answer to that should be in argv[0], which should be the full path of the program itself, which should include the directory the program was launched from. At least that's the convention for argv[0] on most platforms.

    If you mean some other problem, please explain exactly what you want to happen.

    You might also post what other platforms you've programmed on before, so we have some context.
     
  8. Central Limit thread starter macrumors newbie

    Joined:
    Jul 24, 2011
    #8
    Sorry for the confusion.

    You are right, I know how to fix the problem on MY computer. But I want to email this program to a colleague and have him use it on his computer. Since my directory structure is bound to be different from his, I don't want to hard code the file location.

    I will see if I can use argv[0] to fix the problem.
     
  9. lloyddean, Jul 24, 2011
    Last edited: Jul 24, 2011

    lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #9
    This may be of interest -

    Code:
    /* =====================================================================================================================
     * File - main.cpp
     * ---------------------------------------------------------------------------------------------------------------------
     */
    
    /* =====================================================================================================================
     * ---------------------------------------------------------------------------------------------------------------------
     */
    
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <map>
    #include <string>
    #include <utility>
    #include <vector>
    
    
    /* =====================================================================================================================
     * ---------------------------------------------------------------------------------------------------------------------
     */
    
    typedef std::map<const std::string, const std::string>					dict_t;
    typedef std::map<const std::string, const std::string>::iterator		dict_itr;
    typedef std::map<const std::string, const std::string>::const_iterator	dict_const_itr;
    
    
    /* =====================================================================================================================
     * ---------------------------------------------------------------------------------------------------------------------
     */
    
    dict_t	g_dictEnvironment;
    
    
    /* =====================================================================================================================
     * ---------------------------------------------------------------------------------------------------------------------
     */
    
    int main(int argc, char* argv[], char* envv[])
    {
    	using std::cout;
    	using std::endl;
    	using std::ostream_iterator;
    	using std::string;
    	
    	string	strT;
    
    
    	// Insert 'key' named "ApplicationName" with 'value' as the name of this executable into the dictionary
    	// 'g_dictEnvironment' ...
    
    	strT	= argv[0];
    	strT.erase(0, strT.find_last_of('/') + 1);
    	g_dictEnvironment.insert(make_pair("ApplicationName", strT));
    	
    
    	// ... add the environment variables in effect at executables launch into the dictionary 'g_dictEnvironment' ...
    
    	char**	penvvT = envv;
    	do
    	{
    		strT	= *penvvT;
    		g_dictEnvironment.insert(make_pair(strT.substr(0, strT.find('=')), strT.substr(strT.find('=') + 1)));
    	} while ( *++penvvT );
    	
    	// ... request equivalent of shell $HOME ...
    	
    	dict_const_itr	itr	= g_dictEnvironment.find("HOME");
    	if ( itr != g_dictEnvironment.end() )
    	{
    		cout << "Home directory: " << (*itr).second << "\n\n";
    	}
    
    	// ... dump the dictionary 'g_dictEnvironment'
    
    	for ( dict_itr itr = g_dictEnvironment.begin(); itr != g_dictEnvironment.end(); ++itr )
    	{
    		cout << (*itr).first << " = " << (*itr).second << endl;
    	}
    	
        return EXIT_SUCCESS;
    }
    
     

Share This Page