Thread: Thanks again....

  1. #1
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547

    Thanks again....

    I just want to say "Thanks again" to everyone who helped me get past my roadblocks with C++ ... I don't think I'm there yet, but I did manage my first working program today. Couldn't a done it without ya!

    Code:
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <fstream>
    #include <string>
    #include <windows.h>
    #include <shlwapi.h>
    
    using namespace std;
    
    /////////////////////////////////////////////////////////////////////
    // Directory listing in a class
    //
    class DirList
      { private:
          vector <string> Files;
          string Path;
        public:
          DirList();
          DirList(string Folder);
          ~DirList();
          bool GetFiles(string Folder);
          void ListFiles();
          void Sort();
          void Randomize();
          bool SaveList(string Target);
      };
    
      bool DirList::GetFiles(string Folder)
        { Files.clear();
          Path = Folder;
          Folder += "\\*.*";
          WIN32_FIND_DATA fd;
          HANDLE ff = FindFirstFile(Folder.c_str(),&fd);
          if (ff == INVALID_HANDLE_VALUE)
            return false;
          do
           { if (fd.cFileName[0] != '.')
               Files.push_back(Path + "\\" + fd.cFileName); }
          while ( FindNextFile(ff,&fd) );
          FindClose(ff);
          return true; }
    
      void DirList::ListFiles(void)
        { for (unsigned int i = 0; i < Files.size(); i++)
           cout << Files[i] << endl; }
    
      void DirList::Sort(void)
        { sort(Files.begin(),Files.end()); }
    
      void DirList::Randomize(void)
        { random_shuffle(Files.begin(),Files.end()); }
    
      bool DirList::SaveList(string Target)
        { ofstream outfile(Target.c_str());
          if (outfile.fail())    // file not open
            return false;
          for (unsigned int i = 0; i < Files.size(); i++)
            outfile << Files[i] << endl;
          outfile.close();
          return true; }
    
      // structors
      DirList::DirList()
        { cout << "cold init" << endl; }
    
      DirList::DirList(string Folder)
        { GetFiles(Folder); }
    
      DirList::~DirList()
        { cout << endl << "Finished!" << endl; }
    
    
    ////////////////////////////////////////////////////////////////////
    // Help splash
    void ShowHelp(void)
      { cout << "DirToFile -- Save directory lists in files" << endl;
        cout << endl;
        cout << "USAGE :   DirToFile -R <TARGET FILE> <SOURCE FOLDER>" << endl;
        cout << endl;
        cout << "-R Randomize file list (for playlists)" << endl;
        cout << endl;
        cout << "Enclose file and path names with spaces in quotes." << endl;
        cout << endl;
        cout << "Example: DirToFile -r Playlist.m3u \"d:\\My Files\\Music\"" << endl;
        cout << endl << endl;
        exit(0); }
    
    
    /////////////////////////////////////////////////////////////////////
    // Program entry point
    //
    int main(int argv, char* argc[])
      { // helper splash
        if (argv < 3)
          ShowHelp();
    
        // parse command line
        bool    Shuffle = false;
        string  Target  = "test.txt";
        string  Folder  = "";
    
        for (int x = 1; x < argv; x++)
          PathUnquoteSpaces(argc[x]);
    
        if (!strcmp(argc[1],"-R") || (!strcmp(argc[1],"-r")))
          { Shuffle = true;
            if (argc[2])
              Target = argc[2];
            if (argc[3])
              Folder = argc[3]; }
        else
         {  if(argc[1])
              Target = argc[1];
            if (argc[2])
              Folder = argc[2]; }
    
        cout << Target << " from " << Folder << endl;
    
      if (Target.length() < 3)
        ShowHelp();
    
      if (Folder.length() < 1)
        ShowHelp();
    
      // sorted or scrambled
      DirList Dir(Folder);
      if (Shuffle)
        Dir.Randomize();
      else
        Dir.Sort();
    
      // show list on screen
      Dir.ListFiles();
      // write the file
      Dir.SaveList(Target);
      return 0; }
    Now the hard part begins....

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > int main(int argv, char* argc[])
    That's just too confusing!
    Almost everyone writes argc and argv
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Haha yah that got me too

  4. #4
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    omg..your first working C++ program and you wrote this...
    I need help.
    You ended that sentence with a preposition...Bastard!

  5. #5
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Why do you pass strings by value?
    I'd pass them by const reference and even if I needed to change them, I would create a local variable instead.

    And when you work with strings, they might throw exceptions (for example std::bad_alloc) and FindClose will never be called. Same with containers.
    Last edited by kmdv; 01-19-2011 at 05:55 AM.

  6. #6
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Good job.

    My first C++ program, a couple years ago, was to convert ebcdic data downloaded from a mainframe cobol application into ascii-human-readable data for loading into oracle. I learned a lot.
    Mainframe assembler programmer by trade. C coder when I can.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Salem View Post
    > int main(int argv, char* argc[])
    That's just too confusing!
    Almost everyone writes argc and argv
    LOL... It's been a long time since I worked on console code... but... noted for future!

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Eman View Post
    omg..your first working C++ program and you wrote this...
    I need help.
    Don't panic It's my first C++ but I've been programming in C for a while and Pascal before that so you might say I had a little experience to draw on. You'll get past me... and probably sooner than you think.

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by kmdv View Post
    Why do you pass strings by value?
    I'd pass them by const reference and even if I needed to change them, I would create a local variable instead.

    And when you work with strings, they might throw exceptions (for example std::bad_alloc) and FindClose will never be called. Same with containers.
    Ok... examples please and thank you...

  10. #10
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Dino View Post
    Good job.

    My first C++ program, a couple years ago, was to convert ebcdic data downloaded from a mainframe cobol application into ascii-human-readable data for loading into oracle. I learned a lot.
    Thank you... and, yes, I am suitably impressed... Havent seen ebcdic coding since I used to repair the old solenoid interfaces for IBM Selectric typewriters...

  11. #11
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Originally Posted by kmdv View Post
    Why do you pass strings by value?
    I'd pass them by const reference and even if I needed to change them, I would create a local variable instead.

    And when you work with strings, they might throw exceptions (for example std::bad_alloc) and FindClose will never be called. Same with containers.
    Ok... examples please and thank you...
    To pass by constant reference change
    Code:
    bool DirList::GetFiles(string Folder)
    to
    Code:
    bool DirList::GetFiles(const string& Folder)
    in both the declaration and definition.

    Jim

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by jimblumberg View Post
    To pass by constant reference change
    Code:
    bool DirList::GetFiles(string Folder)
    to
    Code:
    bool DirList::GetFiles(const string& Folder)
    in both the declaration and definition.

    Jim
    Thanks... I'll give that a try... (oh the horrible things I'm about to do to this program... )

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by kmdv
    Why do you pass strings by value?
    I'd pass them by const reference and even if I needed to change them, I would create a local variable instead.
    But if you're going to change the string, and decide to pass by value, the copy constructor gets called anyway. I'm not sure why people do this, since parameters are local to a function. I can only make sense of this considering a special string class without a copy constructor but a clone() member function. It makes little difference considering it's the STL being discussed.
    Last edited by whiteflags; 01-19-2011 at 12:26 PM.

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Passing std::string by reference avoids the call of the copy constructor for the function call.


    Jim

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Yeah but his post just read "if I were going to change [the strings], I would create a local variable instead," implying that parameters aren't local. Hence, my confused reply.

Popular pages Recent additions subscribe to a feed