CString printing to an ofstream object

klax33
klax33 used Ask the Experts™
on
I'm trying to get the results of my file search printed to a text output file but the program crashes with an "unhandled exception."  If I remove all references to the ofstream object and just use cout, the program works correctly, but only prints to the screen.  But like I said I need the results in a text file.  Thanks in advance.


#include <afx.h>
#include <iostream>
#include <fstream>

using namespace std;

void Recurse(LPCTSTR pstr, CString search, ofstream output)
{

 CFileFind finder;

 // build a string with wildcards
 CString strWildcard(pstr);
 strWildcard += _T("\\*.*");

 // start working for files
 BOOL bWorking = finder.FindFile(strWildcard);

 while (bWorking)
 {
    bWorking = finder.FindNextFile();

    // skip . and .. files; otherwise, we'd
    // recur infinitely!

    if (finder.IsDots())
       continue;

    // if it's a directory, recursively search it

    if (finder.IsDirectory())
    {
       CString str = finder.GetFilePath();
       Recurse(str, search, output);
    }

     // now look through the files
     else
     {
          CString file;
          file = (LPCTSTR) finder.GetFilePath();
            CString Ext = finder.GetFileName().Mid(finder.GetFileTitle().GetLength());
            if (!Ext.CompareNoCase(search)) //If eqaul to ".txt" or ".TXT"
            {
                    cout << "Found ext " << (LPCTSTR)Ext << " on file " << (LPCTSTR)file << endl;
                 //output << "Found ext " << (LPCTSTR)Ext << " on file " << (LPCTSTR)file << endl;
            }
     }
   
 }

 finder.Close();
}

void main()
{

     ofstream output;
     output.open("output.txt");
    TCHAR drive[4];
    cout << "Enter drive letter and full colon, then press enter" << endl;
    cin >> drive;
    cout << endl << "You Entered -> " << drive << endl;
     TCHAR search[5];
     cout << "Enter extension to look for in the form of \".txt\"" << endl;
     cin >> search;
     cout << endl << "You entereed -> " << search << endl;
     cout << "Searching drive " << drive << " for " << search << " files.";
    Recurse(drive, search, output);
    cout << endl  << endl;
    system("pause");
}
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
You can not pass a stream object by value.
You need to either pass it by reference or via pointer.
Example:
void Recurse(LPCTSTR pstr, CString search, ofstream &output)

Notice the "&" in front of output argument.
Commented:
Modified version of the code:

void Recurse(LPCTSTR pstr, CString search, ofstream &output)
{
     
     CFileFind finder;
     
     // build a string with wildcards
     CString strWildcard(pstr);
     strWildcard += _T("\\*.*");
     
     // start working for files
     BOOL bWorking = finder.FindFile(strWildcard);
     
     while (bWorking)
     {
          bWorking = finder.FindNextFile();
         
          // skip . and .. files; otherwise, we'd
          // recur infinitely!
         
          if (finder.IsDots())
               continue;
         
          // if it's a directory, recursively search it
         
          if (finder.IsDirectory())
          {
               CString str = finder.GetFilePath();
               Recurse(str, search, output);
          }
         
          // now look through the files
          else
          {
               CString file;
               file = (LPCTSTR) finder.GetFilePath();
               CString Ext = finder.GetFileName().Mid(finder.GetFileTitle().GetLength());
               if (!Ext.CompareNoCase(search)) //If eqaul to ".txt" or ".TXT"
               {
                    cout << "Found ext " << (LPCTSTR)Ext << " on file " << (LPCTSTR)file << endl;
               }
          }
         
     }
     
     finder.Close();
}

void main_()
{
     
    ofstream output;
    output.open("output.txt");
     TCHAR drive[4];
     cout << "Enter drive letter and full colon, then press enter" << endl;
     cin >> drive;
     cout << endl << "You Entered -> " << drive << endl;
    TCHAR search[5];
    cout << "Enter extension to look for in the form of \".txt\"" << endl;
    cin >> search;
    cout << endl << "You entereed -> " << search << endl;
    cout << "Searching drive " << drive << " for " << search << " files.";
     Recurse(drive, search, output);
     cout << endl  << endl;
     system("pause");
}

Commented:
You should avoid passing by value when ever possible.
If you don't need a CString type, or an std::string type for your argument, you should use a string pointer instead.
Example:
void Recurse(LPCTSTR pstr, LPCTSTR search, ofstream &output)

Since you're not use any CString functions with search, you don't need this argument to be a CString object.

Author

Commented:
Thank you for your help again.  The majority of the code I used in this program came from different MSDN examples for the CFileFind class.  I'm not very familiar with afx.h and this was really just a side project to get a working utility for the project I am working on.  Thanks again.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial