none
"fout" the application directory

    Question

  •  

    Hi,

     

    I have code where I (1) - get the application directory (2) - print out the application directory

     

    But the problem is that it does not allways print out, it depends where I put the application ".exe" file

    Maybe the problem is that when there is a space it does not print out.  Is there a way to fix this?

     

    Code Snippet

    void ReadInitializeFile(void)
    {

    // With standard string Extract directory
    char szAppPath[MAX_PATH] = "";
    char szAppDirectory[MAX_PATH] = "";
    int ret,i;
    GetModuleFileName(0, szAppPath, sizeof(szAppPath) - 1);
    strncpy(szAppDirectory, szAppPath, strrchr(szAppPath, '\\') - szAppPath);
    szAppDirectory[strlen(szAppDirectory)] = '\0';

    FILE *infile; 
    char temp_name[100];
    strcpy(temp_name, szAppDirectory);
    strcat(temp_name, "\\xInitializeRuns.csv");


    strcpy(cMachineLocation,szAppDirectory); //Save the directory here

     

    fout <<cMachineLocation<<"\n";

    }

     

     

    It works when the application directory = "C:\Input\Test"

    But it does not print out anything when directory = "C:\Documents and Settings\Jeff\Desktop\Import TxtFile archive\1.29.08"

     

    The length of the second directory is 80.

    Tuesday, January 29, 2008 4:04 PM

Answers

  • I rewrote your function using Unicode-aware coding techniques (e.g. use TCHAR instead of char), using safe string functions (from strsafe.h header), and ATL CString class (very well suited to store strings - #include <atlstr.h> ).

     

    You can use the function like this:

     

    Code Snippet

    // Display application directory
    MessageBox(

      NULL,
      GetApplicationDirectory(),
      _T("GetApplicationDirectory:"),
      MB_OK

    );

     

     


    And this is the GetApplicationDirectory() code:

     

    Code Snippet

    //
    // Returns application directory on success, or empty string on error.
    //
    CString GetApplicationDirectory()
    {
        static const int maxAppPathChars = MAX_PATH;
        TCHAR appPath[maxAppPathChars + 1];
        TCHAR appDirectory[maxAppPathChars + 1];

     

        // Clear destination buffer
        ::ZeroMemory( appPath, sizeof(appPath) );
       
        // Get fully-qualified path for the executable
        if ( ! ::GetModuleFileName(NULL, appPath, maxAppPathChars ) )
        {
            // Failure
            return _T("");
        }

     

        // Search last occurrence of '\' character
        const TCHAR * pLastBackSlash = _tcsrchr(appPath, _T('\\'));
        if ( pLastBackSlash == NULL )
        {
            // Not found
            return _T("");
        }

     

        // Get the number of bytes (from TCHARs) to copy, from the beginning
        // of the string, before the last occurrence of '\' found above.
        const size_t bytesToCopy = (pLastBackSlash - appPath) * sizeof(TCHAR);
       
        // Copy the first part of the string, excluding '\' and app name
        if ( FAILED( ::StringCbCopyN(
            appDirectory,
            sizeof(appDirectory),
            appPath,
            bytesToCopy
            ) ) )
        {
            // Error
            return _T("");
        }
       
        // Do a deep-copy of the app directory string
        return CString( appDirectory );
    }

     

     

     

    Giovanni

     

     

     

    Tuesday, January 29, 2008 4:37 PM

All replies

  • I rewrote your function using Unicode-aware coding techniques (e.g. use TCHAR instead of char), using safe string functions (from strsafe.h header), and ATL CString class (very well suited to store strings - #include <atlstr.h> ).

     

    You can use the function like this:

     

    Code Snippet

    // Display application directory
    MessageBox(

      NULL,
      GetApplicationDirectory(),
      _T("GetApplicationDirectory:"),
      MB_OK

    );

     

     


    And this is the GetApplicationDirectory() code:

     

    Code Snippet

    //
    // Returns application directory on success, or empty string on error.
    //
    CString GetApplicationDirectory()
    {
        static const int maxAppPathChars = MAX_PATH;
        TCHAR appPath[maxAppPathChars + 1];
        TCHAR appDirectory[maxAppPathChars + 1];

     

        // Clear destination buffer
        ::ZeroMemory( appPath, sizeof(appPath) );
       
        // Get fully-qualified path for the executable
        if ( ! ::GetModuleFileName(NULL, appPath, maxAppPathChars ) )
        {
            // Failure
            return _T("");
        }

     

        // Search last occurrence of '\' character
        const TCHAR * pLastBackSlash = _tcsrchr(appPath, _T('\\'));
        if ( pLastBackSlash == NULL )
        {
            // Not found
            return _T("");
        }

     

        // Get the number of bytes (from TCHARs) to copy, from the beginning
        // of the string, before the last occurrence of '\' found above.
        const size_t bytesToCopy = (pLastBackSlash - appPath) * sizeof(TCHAR);
       
        // Copy the first part of the string, excluding '\' and app name
        if ( FAILED( ::StringCbCopyN(
            appDirectory,
            sizeof(appDirectory),
            appPath,
            bytesToCopy
            ) ) )
        {
            // Error
            return _T("");
        }
       
        // Do a deep-copy of the app directory string
        return CString( appDirectory );
    }

     

     

     

    Giovanni

     

     

     

    Tuesday, January 29, 2008 4:37 PM
  • Thanks for your help.  Also why is Unicode neccessary? is "fout" not as secure as strings?

     

     

    Tuesday, January 29, 2008 5:46 PM
  • IMHO, ANSI strings are "dinosaurs" for computer technology.

    Every string should be stored as Unicode (be it UTF-16 or UTF-8).

    In fact, Windows internally stores strings as Unicode (UTF-16), and modern programming languages like Python, Java, C# use Unicode to store their strings.

    (If you use ANSI or some code-page based string, sooner or later you will end up in programming troubles, especially when you need to pass text and strings between different computers, over the network, Internet, etc. )

     

    For your second question: I just used CString as a return value for the function. My purpose was to develop a reusable function, that returned a string as output. So I choose to use CString as the string class (the C++ standard library offers std::wstring, but IMHO Microsoft CString class is better designed and works very well for Windows C++ programs).

    CString has an operator LPCTSTR for conversion, which allows you to use the CString instance also in places where a 'const TCHAR *' (a "raw" C string pointer) is required.

     

    HTH,
    Giovanni

     

     

    Tuesday, January 29, 2008 11:01 PM
  •  

    Thanks that is very helpful!
    Wednesday, January 30, 2008 12:33 AM