| Home | Forums | Reviews | Guides | Newsgroups | Register | Search |
![]() |
| Thread Tools |
| sandy@murdocks.on.ca |
|
|
|
| |
|
BobR
Guest
Posts: n/a
|
wrote in message ... > >I THINK I am inserting into my vector correctly; I am sure that I am >not getting back my data. >I did use a vector of pointers to my Directory class: > > vector<Directory*> Directories; // from my .h file In your class, or at global scope? > >In my cpp I then had: >Directories.resize(0); You can just do: Directories.clear(); .....to empty the vector. If you just created 'Directories', it isn't needed, yet. > >to insert into my vector I have this: > >bool Directory::MKDir(){ > string DN; // directory name // > int i; // a counter Problem!! 'i' is not initialised, could be anything. int i( 0 ); // a counter // same result as int i = 0; > > do{ //Get the name of the new file. > if( i > 0 ){ // since 'i' was not initialised, it was more than likely // not zero first pass thru loop. // > cout << "Please enter a valid Directory name." // <<" No spaces and must " // > << "not include a dot." << endl; cout << "Please enter a valid Directory name." "\nNo spaces and must " "not include a dot." <<std::endl; // string literals concatenate. pretty trick, eh? // You want this to print every loop except the first? > } > > cout << "Enter directory name: "; > getline(cin, DN); > > //Check to see if that Directory name is allowed > //ValidName = tmpFile->ValidName(FN); > i++; > }while(DN == "" ); //|| ValidName == false // std::string.empty() returns true if the string is empty. So, you could do: } while( DN.empty() ); //|| ValidName == false > > Directory *ND = new Directory(NULL, DN); > Directories.push_back( ND ); // good. > NumSubDirs++; > } // Directory::MKDir() > >I have tried the following to get access to the 'directory' after I >inserted it into my vector (I think) > > /* for(int i = 0; i < Directories.size(); i++){ > cout << Directories.at( i )->GetName() << " "; // << endl; > } > //Directory *D; > */ > /* for (vector<Directory*>::iterator i = Directories.begin(); i != > Directories.end(); ++i ){ > D = new Directory *i > D.Print() << endl; > }*/ /* That last one is wrong. If you want to use iterators, do: for( vector<Directory*>::iterator i = Directories.begin(); i != Directories.end(); ++i ){ (*i)->Print(); std::cout<<std::endl; } */ > > for(size_t i(0); i < Directories.size(); ++i){ > std::cout<<" Directories.at("<<i<<")= " > <<Directories.at( i )->GetName()<<std::endl; > } // for(i) That should work. This is running inside the class (in a function), right? (or is 'Directories' at global scope?) > >they all compile, but they all crash when I try to use the loop to show >the names of the directories. I have two function associated that I >could use: >.Print() (which does a cout of the name) >.GetName() (which returns the name of the directory) Lesson 83649: 'Crash' means many things. What was the last thing you saw? The more information you give us, the quicker we can come up with a possible solution. Let's try something (I know you aren't ready, but, just copy/paste (delete later)). #include <stdexcept> // for exception { // scope of your function (maybe in your class)/main() try{ for(size_t i(0); i < Directories.size(); ++i){ std::cout<<" Directories.at("<<i<<")= " <<Directories.at( i )->GetName()<<std::endl; } // for(i) } // try catch( std: std::cerr<<" caught: "<<Oor.what()<<std::endl; } catch(...){ std::cerr<<" caught: some other error."<<std::endl; } } // scope of your function Now, run your prog and see which "caught:" you get. This will help narrow down the search for the bug. May be a good idea to post your 'Directory' class (and the definitions for 'Print' and 'GetName', if not inline in the class). > >I am also going to need to sort this thing, so I really need access to >those data elements... well I guess that was a given! <g>. Piece of cake, but, one thing at a time. Find bug first<beats chest like Tarzan>!! > >Also about top-posting... do you mean typing my comments at the top of >the previous users comments? If so; I shall stop. >Thanks. This post was better. Next, trim (delete) old post that you do not need for your reply ( like notice that I cut out your text from prior post and my code which we are done with). -- Bob R POVrookie |
|
|
|
|
|||
|
|||
| BobR |
|
|
|
| |
|
sandy@murdocks.on.ca
Guest
Posts: n/a
|
> > vector<Directory*> Directories; // from my .h file
> > In your class, or at global scope? I am doing this in the private section of my .h file > > > > >In my cpp I then had: > >Directories.resize(0); > > You can just do: > > Directories.clear(); I have done that AND discovered that one of my constructors used 0 and one used 1! I never (really) got to see your code work. When I ran it here's what happened (some conjecture some fact). My directory object was created, setting my vector resize (1) (two slots) I added 1 directory. I then used my 'dir' command to list the files and directories. The program immediately launched a popup asking me to open my visual studio as a debugger (I am writing in Dev C++). The first error I saw pop up was: Unhandled exception at 0x00434b78 in COSC202H_Ass3.exe: 0xC0000005: Access violation reading location 0x00000000. when I pressed continue it would just keep popping back the same error. (That isn't what your catch does is it? I expected a cout on the screen.) Eventually I hit break and this line was highlighted: 00434B78 mov eax,dword ptr [eax] which of course means NOTHING to me. HOWEVER I did find that by fixing my constructor using the method you suggested: Directories.clear(); the problem was fixed. DOH! > >to insert into my vector I have this: > > > >bool Directory::MKDir(){ > > string DN; // directory name > // > int i; // a counter > > Problem!! 'i' is not initialised, could be anything. > int i( 0 ); // a counter > // same result as int i = 0; Thanks. Fixed it. It worked but at some point could have blown up I am sure. > cout << "Please enter a valid Directory name." > "\nNo spaces and must " > "not include a dot." <<std::endl; > // string literals concatenate. pretty trick, eh? > > // You want this to print every loop except the first? Yes. The idea is you create one 'directory' at a time. If you want to make more than one you (from the menu/screen) type mkdir again and go through the process. If you are looping it means your first attempt did not provide a valid name. (error checking is not in place yet). > > > > cout << "Enter directory name: "; > > getline(cin, DN); > > > > //Check to see if that Directory name is allowed > > //ValidName = tmpFile->ValidName(FN); > > i++; > > }while(DN == "" ); //|| ValidName == false > > // std::string.empty() returns true if the string is empty. So, you could do: > > } while( DN.empty() ); //|| ValidName == false > Thanks. > That last one is wrong. If you want to use iterators, do: > for( vector<Directory*>::iterator i = Directories.begin(); > i != Directories.end(); ++i ){ > (*i)->Print(); > std::cout<<std::endl; > } > */ > > > That should work. This is running inside the class (in a function), right? > (or is 'Directories' at global scope?) > Believe it or not it's inside my directories class. From a directory (object) you can create another directory (object) which is a child of the creator (subdirectory). At this point it's all still theory. > Lesson 83649: 'Crash' means many things. What was the last thing you saw? The > more information you give us, the quicker we can come up with a possible > solution. It would list my files (from a prior loop listing files) then launch visual studio to debug (see above). > > Let's try something (I know you aren't ready, but, just copy/paste (delete > later)). > > #include <stdexcept> // for exception > > { // scope of your function (maybe in your class)/main() > > try{ > for(size_t i(0); i < Directories.size(); ++i){ > std::cout<<" Directories.at("<<i<<")= " > <<Directories.at( i )->GetName()<<std::endl; > } // for(i) > > } // try > catch( std: > std::cerr<<" caught: "<<Oor.what()<<std::endl; > } > catch(...){ > std::cerr<<" caught: some other error."<<std::endl; > } > > } // scope of your function > > Now, run your prog and see which "caught:" you get. This will help narrow > down the search for the bug. > May be a good idea to post your 'Directory' class (and the definitions for > 'Print' and 'GetName', if not inline in the class). > okay, here is my .h file: *************************************** #ifndef Directory_h #define Directory_h #include <cstdlib> #include <iostream> #include <string> #include "File.h" #include <vector> //using namespace std; class Directory { private: string Name; // Name of the Directory unsigned int NumSubDirs, NumFiles, MaxSubDirs, MaxFiles; int Level; File *Files; //Pointer to an array of Files vector<Directory*> Directories; // vector to pointers to directories //vector<Directory*>::iterator iter; Directory *Parent; // pointer to this directories parent dir /* DoubleDirectories Input: Directories (array) Output: None Note: Double the size of the Directories array. Initially all arrays will start at 5 (just because). */ void DoubleDirectories(); /* DoubleFiles Input: Files (array) Output: None Note: Double the size of the Files Array. Initially all arrays will start at 5 (just because). */ void DoubleFiles(); /* ClearFiles Input: None Output: None Note: Used to delete all Files from the directory. */ void ClearFiles(); /* ClearDirectories Input: None Output: None Note: Used to delete all sub-directories from this directory. */ void ClearDirectories(); /* FindFile Input: Array of Files, first position, last position key. Output: Int (position in the array of the item if found, otherwise -1) */ int FindFile(File sortedArray[], int first, int last, string key); public: /* Constructor Input: None Output: None Note: Create a new Directory object which is empty. */ Directory(); /* Constructor Input: N (directory name) Output: None Note: Creates a new empty Directory named Name */ Directory(Directory *Parent, string N); /* Empty Input: None Output: Bool Note: Used to check to see if the directory is empty. A directory is empty if it has no files and no subdirectories. } */ bool Empty(); /* Insert Input: CF (Current file) Output: bool Note: Will return false if the file cannot be inserted into the directory. This will occur if the filename is already in use. */ bool Insert(File CF); /* MKFile (make file) Input: Filename Output: bool Note: Used to prompt for input to create a file, then uses Insert to insert the file into the files array. */ bool MKFile(); /* Remove Input: FN (File name) Output: bool Note: Will remove a file from the directory if it can be found. Will return false if the file was not found. */ bool Remove(string FN); /* Create Input: Dir (Subdirectory) Output: bool Note: Will attempt to add a subdirectory to this directory. Returns false if this cannot be done (duplicate). */ bool Create(Directory Dir); bool MKDir(); /* Delete Input: DN (Directory Name) Output: None Note: Used to delete a subdirectory and all of it's contents. */ bool Delete(string DN); bool Delete(); bool DeleteFile(int i); /* Move Input: DN (Directory Name) Output: bool Note: Will move to the parent directory (..) or a subdirectory as required. Returns true or false for success. Asking for parent of the root will return false. Asking for a subdir where it cannot be found will return false. */ bool Move(string DN); /* Input: None Output: bool Note: Will print the contents of this directory(files) and ALL SUBDIRECTORIES. Uses the property Level to determin how many characters to indent before each line of output. will return false if there is nothing to print. */ void Print(); /* SMPrint (Small Print) Input: None Output: None Note: Prints only the content of the current directory and not of any subdirectories. */ void SMPrint(); /* GetNumFiles Input: None Output: None */ int GetNumFiles(); void insertionSort ( File A [ ], int low, int high ); inline void Directory::swap ( File & x, File & y ); /* QuickSort */ void FilesQuickSort ( File A [ ], int low, int high ); /* FindFile */ int FindFile(File sortedArray[], int first, int last, int key); /* GetFileCount */ int FileCount(); /* FindFile Input: F (File) Output: bool Note: will find a file matching the file passed in will return true if found. */ bool FileExists(File &F); string GetName(); }; #endif ********************************* here is my .cpp file: #include "Directory.h" #include <stdexcept> // for exception //#include <iostream> //#include <cstdlib> //#include <string> /* Constructor */ Directory: { Name = ""; NumSubDirs = 0; NumFiles = 0; MaxSubDirs = 5; MaxFiles = 5; Level = -1; //Directories.resize(MaxSubDirs){NULL}; Directories.clear(); //Directories.push_back(new Directory); Files = new File[MaxFiles]; } Directory: { Name = N; NumSubDirs = 0; NumFiles = 0; MaxSubDirs = 5; MaxFiles = 5; Level = -1; Directories.clear(); Files = new File[MaxFiles]; } /* DoubleFiles (Double array file size) */ void Directory: { File * OldArray = Files; Files = new File[MaxFiles * 2]; for(int i = 0; i <= MaxFiles -1; i++) { Files[i] = new File(OldArray[i].GetFileName()); } delete [] OldArray; MaxFiles = MaxFiles * 2; } //Empty() bool Directory::Empty() { if(NumSubDirs == 0 && NumFiles == 0) return true; else return false; } //MKFile() bool Directory::MKFile() { string FN; //File name //system("cls"); // clear screen int i = 0; bool ValidName = false; File *tmpFile = new File; //Get the name of the new file. do { if(i > 0) { cout << "Please enter a valid file name. No spaces and must "; cout << "include a dot." << endl; } cout << "Enter file name: "; getline(cin, FN); //Check to see if that file name is allowed ValidName = tmpFile->ValidName(FN); i++; }while(FN.empty() || ValidName == false); if(NumFiles > 0 && FindFile(Files, 0, NumFiles, FN)< 0) { // this would be a unique file Files[NumFiles] = tmpFile; if(NumFiles == MaxFiles -1) { DoubleFiles(); // double the size of the files array } NumFiles++; } else if(NumFiles == 0) { // this would be a unique file Files[NumFiles] = tmpFile; if(NumFiles == MaxFiles -1) { DoubleFiles(); // double the size of the files array } NumFiles++; } else { // Error checking //cout << "NumFiles: " << NumFiles << endl; //cout << "FindFiles = " << FindFile(Files, 0, NumFiles, FN); delete tmpFile; cout << "** Error: File already exists. Aborted." << endl; system("PAUSE"); } } bool Directory::MKDir() { string DN; // directory name int i = 0; // a counter //Get the name of the new file. do { if(i > 0) { cout << "Please enter a valid Directory name. No spaces and must "; cout << "not include a dot." << endl; } cout << "Enter directory name: "; getline(cin, DN); //Check to see if that Directory name is allowed //ValidName = tmpFile->ValidName(FN); i++; }while(DN.empty()); //|| ValidName == false Directory *ND = new Directory(NULL, DN); Directories.push_back(ND); NumSubDirs++; } bool Directory: { int index, i; string Item; bool result; system("cls"); //SMPrint(); do { if(i > 0) { cout << "Enter the name of the item you wish to delete: " << endl; cout << "->"; } getline(cin, Item); i++; }while(Item == ""); //search for a file with that name index = FindFile(Files, 0, NumFiles, Item); //cout << "FindFile index = " << index << endl; if(index > -1) { result = DeleteFile(index); cout << "Deleted." << endl; system("PAUSE"); } } bool Directory: { int j; //create a new array and copy all elements to it except the one to be // deleted File * OldArray = Files; *Files = new File[MaxFiles]; for(j = 0; j <= NumFiles -1; j++) { //cout << "j = " << j << endl; if(j < i) { Files[j] = new File(OldArray[j].GetFileName()); //cout << "Moved " << OldArray[j].GetFileName() << " to Files" << endl; } else { Files[j] = new File(OldArray[j+1].GetFileName()); //cout << "Moved " << OldArray[j+1].GetFileName() << " to Files" << endl; } } NumFiles--; //decriment NumFiles delete [] OldArray; return true; } //GetNumFiles int Directory::GetNumFiles() { return NumFiles; } //SMPrint (Small Print) void Directory::SMPrint() { FilesQuickSort (Files, 0, NumFiles -1 ); for(int i = 0; i <= NumFiles -1; i++) { Files[i].Print(); cout << endl; } try{ for(size_t i(0); i < Directories.size(); ++i) { std::cout<<" Directories.at("<<i<<")= " <<Directories.at( i )->GetName()<<std::endl; } // for(i) } // try catch( std: { std::cerr<<" caught: "<<Oor.what()<<std::endl; } catch(...){ std::cerr<<" caught: some other error."<<std::endl; } } void Directory::insertionSort ( File A [ ], int low, int high ) { for ( int p = low+1; p <= high; p++ ) { File tmp = A [ p ]; int j; for ( j = p; j > low && tmp < A [ j-1 ]; j-- ) A [ j ] = A [ j-1 ]; A [ j ] = tmp; } } inline void Directory::swap ( File & x, File & y ) { File temp = x; x = y; y = temp; } //QuickSort // Best and average case time complexity of quickSort : O(n log n ) // Worst case time complexity of quickSort : O(n^2) void Directory::FilesQuickSort ( File A [ ], int low, int high ) { if ( low + 10 > high ) insertionSort ( A, low, high ); else { // Sort low, middle and high int middle = ( low + high ) / 2; if ( A [ middle ] < A [ low ] ) swap ( A [ low ], A [ middle ] ); if ( A [ high ] < A [ low ] ) swap ( A [ low ], A [ high ] ); if ( A [ high ] < A [ middle ] ) swap ( A [ middle ], A [ high ] ); // Place pivot at position high - 1 File pivot = A [ middle ]; swap ( A [ middle ], A [ high-1 ] ); // Partition around the pivot int i, j; for ( i = low, j = high-1; ; ) { while ( A [ ++i ] < pivot ) { } while ( pivot < A [ --j ] ) { } if ( i < j ) swap ( A [ i ], A [ j ] ); else break; } swap ( A [ i ], A [ high-1 ] ); FilesQuickSort ( A, low, i-1 ); FilesQuickSort ( A, i+1, high ); } } /* FindFile */ int Directory::FindFile(File sortedArray[], int first, int last, string key) { while (first <= last) { int mid = (first + last) / 2; // compute mid point. if (sortedArray[mid] < key) first = mid + 1; // repeat search in top half. else if (sortedArray[mid] > key) last = mid - 1; // repeat search in bottom half. else return mid; // found it. return position ///// } return -(first + 1); // failed to find key } int Directory::FileCount() { return NumFiles; } bool Directory::FileExists(File &F) { if(FindFile(Files, 0, NumFiles, F.GetFileName()) > -1) return true; else return false; } string Directory::GetName() { return Name; } void Directory: { cout << Name; } ******************************************* > > > >I am also going to need to sort this thing, so I really need access to > >those data elements... well I guess that was a given! <g>. > > Piece of cake, but, one thing at a time. Find bug first<beats chest like > Tarzan>!! > > > > >Also about top-posting... do you mean typing my comments at the top of > >the previous users comments? If so; I shall stop. > >Thanks. > > This post was better. Next, trim (delete) old post that you do not need for > your reply ( like notice that I cut out your text from prior post and my code > which we are done with). > > -- > Bob R > POVrookie Thanks for all the time and effort. I'd particularly like to get that try catch working. I asked about it in class but was told that isn't taught in this class (or the one prior). I'd like it not so much for throwing errors, but to catch all the weird input that I didn't expect and be able to recover with a 'hey dummy type something that makes sense' kind of message! |
|
|
|
|
|||
|
|||
| sandy@murdocks.on.ca |
|
BobR
Guest
Posts: n/a
|
wrote in message ... >Access violation reading location 0x00000000. Look for a pointer that was never set to anything. > >I'd particularly like to get that try catch working. I asked about it >in class but was told that isn't taught in this class (or the one >prior). I'd like it not so much for throwing errors, but to catch all >the weird input that I didn't expect and be able to recover with a 'hey >dummy type something that makes sense' kind of message! I'll check out your code in a little bit[1]. Thought I'd throw(pun) you a bone in the meantime. Get "Thinking in C++", 2nd ed. Volume 1&2 by Bruce Eckel (available for free here. You can buy it in hardcopy too.): http://www.mindview.net/Books/TICPP/...ngInCPP2e.html In Vol 2, Part 1, there is a chapter on 'Exception Handling'. Some of it may be over your head, but, he gives enough examples that you should be able to figure it out. Be aware that the way you(we) want to use exceptions is a slightly improper use. However, I have found it a useful tool for narrowing down a problem area (bug hunting) while developing new code. Normally, you would only use exceptions to handle situations that can't be delt with in normal program flow. At a top level, you can do: int main(){ using std::cerr; using std::endl; try{ // your code here if( true ){ throw "Help Me!!";} } // try catch( std::bad_alloc const &ba ){ cerr << "Out of memory! " << ba.what() << endl; } catch( std::runtime_error const &re ){ cerr << re.what() << endl; } catch( char const *r_e ){ // catch "Help Me!!" cerr<<"error: " << r_e << endl; } // as many catch() clauses as you need catch(...){ // a 'catch all' cerr << "caught something not caught above" << endl; } return 0; } // main() Also, I noticed you said something about 'Dev-C++'. It defaults to MinGW(GCC). If you build a debug version of your program (using -g switch, or one of it's variants), and then jump to the ms debugger, you may get false information. If you build with GCC, you should use 'gdb' (the GCC debugger). I don't know if 'Insight' is still alive. It was a nice front-end for gdb and worked nice wirh Dev-C++. Maybe 'Google' for it if interested (there was a link on the Bloodshed site). I'll get back to you on your Directory class (if one of the experts in this NG don't 'correct' it first). [1] - first pass through I think I spotted some potential problems. Need to check it out more so I don't send you down the wrong path. -- Bob R POVrookie |
|
|
|
|
|||
|
|||
| BobR |
|
BobR
Guest
Posts: n/a
|
wrote in message ... > > I never (really) got to see your code work. When I ran it >here's what happened (some conjecture some fact). > >My directory object was created, setting my vector resize (1) (two >slots) One 'slot', index 0. As soon as you push_back() once, the max valid index goes to 1 ( so now you have 0 and 1). > I added 1 directory. I then used my 'dir' command to list the >files and directories. The program immediately launched a popup asking >me to open my visual studio as a debugger (I am writing in Dev C++). OK, I can't be sure yet, but I think your one of your problems is with 'FilesQuickSort()'. Comment that out of your program temporarily (read below first). I don't know what is in your "File.h". < just a thought > Now, here is a bigger problem. You use a pointer to a dynamic allocated array ('*Files'). If you do anything that needs to copy the Directory class object (std containers use copy constructor), the default copy constructor just copies the pointer, no new allocation takes place. That's is a big problem, all the copies are trying (could be) to work on the same realestate. That may be the problem in 'FilesQuickSort()'. Rule Of Three (or two, if you use smart pointers)! Let's do a test: class Directory{ private: // Prevent assignment and copy-construction: Directory( Directory const & ); // just this, don't define it. void operator=( Directory const & ); // rest of your class }; // class Directory Now, try to compile it. Work? ( it should not ). A little side note: a class defaults to 'private', so you don't need to put 'private:' at the very top of your class. class Directory{ // this part is private public: // this part is public private: // this part is private again }; // class Directory Your class also needs a destructor that will clean up 'Files'. As is, you have a memory leak. Directory::~Directory(){ delete[] Files; // and since your vector holds pointers to 'new' objects. for( size_t i(0); i < Directories.size(); ++i ){ delete Directories.at( i ); } } // Dtor If the vector held actual objects, it would do all the cleanup for you. Your book should have something on copy constructors and assignment operators. ( If not, 'Thinking in C++' vol 1 does. ) >when I pressed continue it would just keep popping back the same error. >( ** That isn't what your catch does is it? ** I expected a cout on the >screen.) No. If it got to 'catch(...)', it would have put a message on crt. (but not everything gets caught by that) If you had put the FilesQuickSort() call inside the try{}, you may have seen a message. Try it and see (may give another clue). >********************************* >here is my .cpp file: > >#include "Directory.h" >#include <stdexcept> // for exception > >//#include <iostream> >//#include <cstdlib> >//#include <string> > >/* Constructor */ >Directory: > Name = ""; > NumSubDirs = 0; > NumFiles = 0; > MaxSubDirs = 5; > MaxFiles = 5; > Level = -1; > > //Directories.resize(MaxSubDirs){NULL}; > Directories.clear(); > //Directories.push_back(new Directory); > Files = new File[MaxFiles]; >} Unless your instructor expressly prohibited it, you should learn to use 'initialiser lists'. Directory: Name( "" ), // a coma after all but last NumSubDirs( 0 ), NumFiles( 0 ), MaxSubDirs( 5 ), MaxFiles( 5 ), Level( -1 )// no coma { Directories.clear(); Files = new File[MaxFiles]; } // Directory Ctor default >/* DoubleFiles (Double array file size) */ >void Directory: > File * OldArray = Files; > Files = new File[MaxFiles * 2]; > for(int i = 0; i <= MaxFiles -1; i++){ > Files[i] = new File(OldArray[i].GetFileName()); > } > delete [] OldArray; > MaxFiles = MaxFiles * 2; > } If you also make 'Files' a std::vector, you won't need things like 'DoubleFiles()'. >//Empty() If std::vector<File> Files, just: if( Files.empty() ){ /* do whatever */ } >//GetNumFiles Files.size() std::sort( Files.begin(), Files.end() ); // but, you may need to write a 'predicate' to sort the way you want. // dependes on what 'File' is. std::unique( Files.begin(), Files.end() ); // remove dups. // but, you may need to write a 'predicate'. // dependes on what 'File' is. Starting to see the value of the std containers and library? >void Directory::insertionSort ( File A [ ], int low, int high ){ if( ( low < 0 ) || ( high > MaxFiles ) ){ return; } Murphy's laws: If more than one thing can go wrong, the one that will go wrong is the one that will do the most damage! > for ( int p = low+1; p <= high; p++ ){ > File tmp = A [ p ]; > int j; > > for ( j = p; j > low && tmp < A [ j-1 ]; j-- ) > A [ j ] = A [ j-1 ]; > > A [ j ] = tmp; > } >} >******************************************* Work on those things a little, and come back. Nobody ever said C++ was easy! Hang in there! -- Bob R POVrookie |
|
|
|
|
|||
|
|||
| BobR |
|
sandy@murdocks.on.ca
Guest
Posts: n/a
|
BobR wrote: > wrote in message ... > > OK, I can't be sure yet, but I think your one of your problems is with > 'FilesQuickSort()'. > Comment that out of your program temporarily (read below first). > Actually my QuickSort works. I had to overload operators for it to do so, but it seems to be fine. > I don't know what is in your "File.h". > > < just a thought > > Now, here is a bigger problem. You use a pointer to a dynamic allocated array > ('*Files'). If you do anything that needs to copy the Directory class object > (std containers use copy constructor), the default copy constructor just > copies the pointer, no new allocation takes place. That's is a big problem, > all the copies are trying (could be) to work on the same realestate. That may > be the problem in 'FilesQuickSort()'. > Rule Of Three (or two, if you use smart pointers)! > I know. And I think the destructor is going to be a pain too. I think I will have to loop through the array and delete each pointer to each file. The problem that this solves? is that I need to be able to 'loop' and create a new object multiple times. I don't know how to do that except with a pointer; as in x = new file. Also if I 'hard-coded' file x, then it would go out of scope and be deleted at the end of the function even if I put it into a public array would it not? > Let's do a test: > > class Directory{ > private: > > // Prevent assignment and copy-construction: > Directory( Directory const & ); // just this, don't define it. > void operator=( Directory const & ); > > // rest of your class > }; // class Directory > > Now, try to compile it. Work? ( it should not ). Umm... it did work actually. Here is the 'new' header: ************************************************** ********* #ifndef Directory_h #define Directory_h #include <cstdlib> #include <iostream> #include <string> #include "File.h" #include <vector> //using namespace std; class Directory{ private: // Prevent assignment and copy-construction: Directory( Directory const & ); // just this, don't define it. void operator=( Directory const & ); /* class Directory { private: */ string Name; // Name of the Directory unsigned int NumSubDirs, NumFiles, MaxSubDirs, MaxFiles; int Level; File *Files; //Pointer to an array of Files vector<Directory*> Directories; // vector to pointers to directories //vector<Directory*>::iterator iter; Directory *Parent; // pointer to this directories parent dir /* DoubleDirectories Input: Directories (array) Output: None Note: Double the size of the Directories array. Initially all arrays will start at 5 (just because). */ void DoubleDirectories(); /* DoubleFiles Input: Files (array) Output: None Note: Double the size of the Files Array. Initially all arrays will start at 5 (just because). */ void DoubleFiles(); /* ClearFiles Input: None Output: None Note: Used to delete all Files from the directory. */ void ClearFiles(); /* ClearDirectories Input: None Output: None Note: Used to delete all sub-directories from this directory. */ void ClearDirectories(); /* FindFile Input: Array of Files, first position, last position key. Output: Int (position in the array of the item if found, otherwise -1) */ int FindFile(File sortedArray[], int first, int last, string key); public: /* Constructor Input: None Output: None Note: Create a new Directory object which is empty. */ Directory(); /* Constructor Input: N (directory name) Output: None Note: Creates a new empty Directory named Name */ Directory(Directory *Parent, string N); /* Empty Input: None Output: Bool Note: Used to check to see if the directory is empty. A directory is empty if it has no files and no subdirectories. } */ bool Empty(); /* Operator == Inputs: string D (directory name) Output: bool Note: Used to detect if a directory name matches a string. For example, two Directories of the same parent cannot have the same name. */ bool operator==(const string &D); /* operator < Inputs: Directory D Outputs: bool Notes: Used to determine if the NAME of the directory is less than (before) the one compared. */ bool operator<(const Directory & D); //Note to self pointer to D??? /* operator < Inputs: DN (Directory name) Outputs: bool Notes: If the Directory name is < the 'other' Directory name True. */ bool operator<(string DN); /* operator > Inputs: Directory D Outputs: bool Note: Used to determine if the NAME of the directory is greater than the other. */ bool operator>(const Directory & D); /* operator > Inputs: DN (string file name) Outputs: bool Note: Uses a string value to compare a string to the NAME of the directory. */ bool operator>(string DN); /* Insert Input: CF (Current file) Output: bool Note: Will return false if the file cannot be inserted into the directory. This will occur if the filename is already in use. */ bool Insert(File CF); /* MKFile (make file) Input: Filename Output: bool Note: Used to prompt for input to create a file, then uses Insert to insert the file into the files array. */ bool MKFile(); /* Remove Input: FN (File name) Output: bool Note: Will remove a file from the directory if it can be found. Will return false if the file was not found. */ bool Remove(string FN); /* Create Input: Dir (Subdirectory) Output: bool Note: Will attempt to add a subdirectory to this directory. Returns false if this cannot be done (duplicate). */ bool Create(string Dir); bool MKDir(); /* Delete Input: DN (Directory Name) Output: None Note: Used to delete a subdirectory and all of it's contents. */ bool Delete(string DN); bool Delete(); bool DeleteFile(int i); /* Move Input: DN (Directory Name) Output: bool Note: Will move to the parent directory (..) or a subdirectory as required. Returns true or false for success. Asking for parent of the root will return false. Asking for a subdir where it cannot be found will return false. */ bool Move(string DN); /* Input: None Output: bool Note: Will print the contents of this directory(files) and ALL SUBDIRECTORIES. Uses the property Level to determin how many characters to indent before each line of output. will return false if there is nothing to print. */ void Print(); /* SMPrint (Small Print) Input: None Output: None Note: Prints only the content of the current directory and not of any subdirectories. */ void SMPrint(); /* GetNumFiles Input: None Output: None */ int GetNumFiles(); void insertionSort ( File A [ ], int low, int high ); //void insertionSort (vector<Directory*> A, int low, int high); inline void swap ( File & x, File & y ); //inline void swap (Directory & x, Directory & y); /* QuickSort */ void QuickSort ( File A [ ], int low, int high ); //void QuickSort (vector<Directory> A, int low, int high); /* FindFile */ int FindFile(File sortedArray[], int first, int last, int key); /* GetFileCount */ int FileCount(); /* FindFile Input: F (File) Output: bool Note: will find a file matching the file passed in will return true if found. */ bool FileExists(File &F); string GetName(); }; #endif ********************************************** > > A little side note: a class defaults to 'private', so you don't need to put > 'private:' at the very top of your class. > class Directory{ > // this part is private > public: > // this part is public > private: > // this part is private again > }; // class Directory > The prof is big on seeing those words though. It does make it clearer too. > Your class also needs a destructor that will clean up 'Files'. As is, you > have a memory leak. > Yup. A big nasty one. I will have to loop through and delete each File from the array, then the array. Big pain, but I think that's the point. > Directory::~Directory(){ > delete[] Files; > // and since your vector holds pointers to 'new' objects. > for( size_t i(0); i < Directories.size(); ++i ){ > delete Directories.at( i ); > } > } // Dtor > > If the vector held actual objects, it would do all the cleanup for you. > How can I dynamically create actual objects though? They do go out of scope at the end of the function don't they? > If you had put the FilesQuickSort() call inside the try{}, you may have seen > a message. Try it and see (may give another clue). > I think the old bug is quite fixed. I have been using it for a while with no problem, even adding subdirectories. The QuickSort works for my Files (putting them in alphabetical order). The sort for the vector however does not seem to. In fact I cannot see it changing anything. I added code to read a comma delimited file with a bunch of random words in it. I use that to create directories (who wants to type all that!) the vector sort is given at the end of each addition, I then list the directory and the files come back out in the order they went in. My suspicion is that they are sorted by the pointer, not the thing pointed to. I am looking at that but.... > here is the new cpp file, it has changed a little to accomodate things like automated directory addition. ********************************* #include "Directory.h" #include <stdexcept> // for exception //#include <iostream> //#include <cstdlib> //#include <string> /* Constructor */ Directory: { Name = ""; NumSubDirs = 0; NumFiles = 0; MaxSubDirs = 5; MaxFiles = 5; Level = -1; //Directories.resize(MaxSubDirs){NULL}; Directories.clear(); //Directories.push_back(new Directory); Files = new File[MaxFiles]; } Directory: { Name = N; NumSubDirs = 0; NumFiles = 0; MaxSubDirs = 5; MaxFiles = 5; Level = -1; Directories.clear(); Files = new File[MaxFiles]; } /* operator== */ bool Directory: { if(Name != D) return false; else return true; } bool Directory: { // both names are strings so this should work. //if the Directory Name is >, then false if(Name > D.Name) return false; //if the Directory Name is <, then true if(Name < D.Name) return true; } /* operator> */ bool Directory: { if(Name < D.Name) return false; if(Name > D.Name) return true; } /* DoubleFiles (Double array file size) */ void Directory: { File * OldArray = Files; Files = new File[MaxFiles * 2]; for(int i = 0; i <= MaxFiles -1; i++) { Files[i] = new File(OldArray[i].GetFileName()); } delete [] OldArray; MaxFiles = MaxFiles * 2; } //Empty() bool Directory::Empty() { if(NumSubDirs == 0 && NumFiles == 0) return true; else return false; } //MKFile() bool Directory::MKFile() { string FN; //File name //system("cls"); // clear screen int i = 0; bool ValidName = false; File *tmpFile = new File; //Get the name of the new file. do { if(i > 0) { cout << "Please enter a valid file name. No spaces and must "; cout << "include a dot." << endl; } cout << "Enter file name: "; getline(cin, FN); //Check to see if that file name is allowed ValidName = tmpFile->ValidName(FN); i++; }while(FN.empty() || ValidName == false); if(NumFiles > 0 && FindFile(Files, 0, NumFiles, FN)< 0) { // this would be a unique file Files[NumFiles] = tmpFile; if(NumFiles == MaxFiles -1) { DoubleFiles(); // double the size of the files array } NumFiles++; QuickSort (Files, 0, NumFiles -1 ); } else if(NumFiles == 0) { // this would be a unique file Files[NumFiles] = tmpFile; if(NumFiles == MaxFiles -1) { DoubleFiles(); // double the size of the files array } NumFiles++; } else { // Error checking //cout << "NumFiles: " << NumFiles << endl; //cout << "FindFiles = " << FindFile(Files, 0, NumFiles, FN); delete tmpFile; cout << "** Error: File already exists. Aborted." << endl; system("PAUSE"); } } bool Directory::MKDir() { string DN; // directory name int i = 0; // a counter bool result; //Get the name of the new file. do { if(i > 0) { cout << "Please enter a valid Directory name. No spaces and must "; cout << "not include a dot." << endl; } cout << "Enter directory name: "; getline(cin, DN); //Check to see if that Directory name is allowed //ValidName = tmpFile->ValidName(FN); i++; }while(DN.empty()); //|| ValidName == false //create the directory result = Create(DN); } bool Directory::Create(string DN) { Directory *ND = new Directory(this, DN); Directories.push_back(ND); NumSubDirs++; std::sort(Directories.begin(), Directories.end()); return true; } bool Directory: { int index, i; string Item; bool result; system("cls"); //SMPrint(); do { if(i > 0) { cout << "Enter the name of the item you wish to delete: " << endl; cout << "->"; } getline(cin, Item); i++; }while(Item == ""); //search for a file with that name index = FindFile(Files, 0, NumFiles, Item); //cout << "FindFile index = " << index << endl; if(index > -1) { result = DeleteFile(index); cout << "Deleted." << endl; system("PAUSE"); } } bool Directory: { int j; //create a new array and copy all elements to it except the one to be // deleted File * OldArray = Files; *Files = new File[MaxFiles]; for(j = 0; j <= NumFiles -1; j++) { //cout << "j = " << j << endl; if(j < i) { Files[j] = new File(OldArray[j].GetFileName()); //cout << "Moved " << OldArray[j].GetFileName() << " to Files" << endl; } else { Files[j] = new File(OldArray[j+1].GetFileName()); //cout << "Moved " << OldArray[j+1].GetFileName() << " to Files" << endl; } } NumFiles--; //decriment NumFiles delete [] OldArray; return true; } //GetNumFiles int Directory::GetNumFiles() { return NumFiles; } //SMPrint (Small Print) void Directory::SMPrint() { //cout << NumFiles; if( NumFiles > 0) { for(int i = 0; i <= NumFiles -1; i++) { Files[i].Print(); cout << endl; } } if(Directories.size() > 0) { try { for(size_t i(0); i < Directories.size(); ++i) { cout << Directories.at( i )->GetName()<< endl; } // for(i) } // try catch( std: { std::cerr<<" caught: "<<Oor.what()<<std::endl; } catch(...) { std::cerr<<" caught: some other error."<<std::endl; } } cout << NumFiles << " Files and " << Directories.size() << " Directories" << endl; } void Directory::insertionSort ( File A [ ], int low, int high ) { for ( int p = low+1; p <= high; p++ ) { File tmp = A [ p ]; int j; for ( j = p; j > low && tmp < A [ j-1 ]; j-- ) A [ j ] = A [ j-1 ]; A [ j ] = tmp; } } /* void Directory::insertionSort ( vector<Directory*> A , int low, int high ) { for ( int p = low+1; p <= high; p++ ) { Directory *tmp = A [ p ]; int j; for ( j = p; j > low && tmp < A [ j-1 ]; j-- ) A [ j ] = A [ j-1 ]; A [ j ] = tmp; } } */ inline void Directory::swap ( File & x, File & y ) { File temp = x; x = y; y = temp; } /* inline void Directory::swap (Directory &x, Directory &y) { Directory temp = x; x = y; y = temp; } */ //QuickSort // Best and average case time complexity of quickSort : O(n log n ) // Worst case time complexity of quickSort : O(n^2) //QuickSort // Best and average case time complexity of quickSort : O(n log n ) // Worst case time complexity of quickSort : O(n^2) void Directory::QuickSort ( File A [ ], int low, int high ) { if ( low + 10 > high ) insertionSort ( A, low, high ); else { // Sort low, middle and high int middle = ( low + high ) / 2; if ( A [ middle ] < A [ low ] ) swap ( A [ low ], A [ middle ] ); if ( A [ high ] < A [ low ] ) swap ( A [ low ], A [ high ] ); if ( A [ high ] < A [ middle ] ) swap ( A [ middle ], A [ high ] ); // Place pivot at position high - 1 File pivot = A [ middle ]; swap ( A [ middle ], A [ high-1 ] ); // Partition around the pivot int i, j; for ( i = low, j = high-1; ; ) { while ( A [ ++i ] < pivot ) { } while ( pivot < A [ --j ] ) { } if ( i < j ) swap ( A [ i ], A [ j ] ); else break; } swap ( A [ i ], A [ high-1 ] ); QuickSort ( A, low, i-1 ); QuickSort ( A, i+1, high ); } } /* FindFile */ int Directory::FindFile(File sortedArray[], int first, int last, string key) { while (first <= last) { int mid = (first + last) / 2; // compute mid point. if (sortedArray[mid] < key) first = mid + 1; // repeat search in top half. else if (sortedArray[mid] > key) last = mid - 1; // repeat search in bottom half. else return mid; // found it. return position ///// } return -(first + 1); // failed to find key } int Directory::FileCount() { return NumFiles; } bool Directory::FileExists(File &F) { if(FindFile(Files, 0, NumFiles, F.GetFileName()) > -1) return true; else return false; } string Directory::GetName() { return Name; } void Directory: { cout << Name; } ************************************************ Not that I want to over do it, but here's the 'controlling' app called FileSystem: header: ************************************************ #ifndef FileSystem_h #define FileSystem_h #include <cstdlib> #include <iostream> #include <string> #include "Directory.h" using namespace std; class FileSystem { private: Directory *CurrentDir, *RootDir; public: /* constructor */ FileSystem(); /* Destructor */ ~FileSystem(); /* main inputs: none outputs: none Note: used start the application process. */ void main(); /* mkdir inputs: none output: none Note: used to make a new sub-directory of the current directory. */ void mkdir(); /* mkfile input: none output: none Note: used to make a new file */ void mkfile(); /* del input: none output: none Note: used to delete BOTH files and directories. Will search for a matching file, if none is found will search for a directory to delete. */ void del(); /* dir input: none output: none Note: used to list the contents of the current directory. */ void dir(); /* move input: none output: none Note: used to either move to the parent directory or to a subdir. */ void move(); /* input: none output: none Note: used to list the contents of the current directory and subdirectories. */ void print(); /* count intput: none output: none Note: used to return a count of all of the files in the system from the current directory to it's lowest child. */ void count(); /* help input: none output: none Note: Help */ void help(); /* ShowCursor input: none output: none Note: creates the cursor (->) on the screen. */ void ShowCursor(); /* toupper input: string output: string Note: I found that toupper only works for characters, so I wrote one for strings. (WHY ISN"T THERE ONE???) */ string toupper(string S); /******************** used for testing ********/ // loads an array from a text file void openInFile(); // list test array contents void ListTestArray(); void FileSystem::TestMakeDirs() }; #endif ****************************************** Code: ******************************************* #include "FileSystem.h" #include <iostream> #include <cstdlib> #include <string> #include <iomanip> #include <fstream> // An array used for testing only int AS = 50; //Size of Array, Array Size int CS = 0; // current size (in use) string Words[50]; using namespace std; FileSystem::FileSystem() { RootDir = new Directory(NULL, "/"); CurrentDir = RootDir; } FileSystem::~FileSystem() { } void FileSystem::ShowCursor() { cout << "-> "; } void FileSystem::help() { cout << "The following commands are available." << endl; cout << "COUNT"; cout.width(10); cout << "DEL"; cout.width(10); cout << "DIR"; cout.width(10); cout << "HELP"; cout << endl; cout << "MKDIR"; cout.width(10); cout << "MKFILE"; cout.width(10); cout << "MOVE"; cout.width(10); cout << "PRINT"; cout << endl; cout << "QUIT" << endl << "Type 'HELP' to see this list again."; cout << endl; } void FileSystem::main() { string command; help(); //ShowCursor(); //getline(cin, command); do { ShowCursor(); getline(cin, command); command = toupper(command); //Can't use switch with a string... if then else I guess... // help menu if(command == "HELP") { system("cls"); help(); } // make a file else if(command == "MKFILE") { system("cls"); CurrentDir->MKFile(); } // make a directory else if(command == "MKDIR") { system("cls"); CurrentDir->MKDir(); } // show files and subdirs for current directory else if(command == "DIR") { system("cls"); CurrentDir->SMPrint(); } // delete (a file or directory) else if(command == "DEL") { system("cls"); CurrentDir->Delete(); } // Quit else if(command == "QUIT") { system("cls"); cout << "Quiting" << endl; } else if (command == "LOADARRAY") { openInFile(); } else if(command == "SHOWARRAY") { ListTestArray(); } else if(command == "TESTMKDIR") { TestMakeDirs(); } else { cout << "Un-recognized command" << endl; } }while(command != "QUIT"); } string FileSystem::toupper(string S) { for (int j=0; j<S.length(); ++j) { S[j]=std::toupper(S[j]); } return S; } /************************ Code for Testing only ********/ void FileSystem: { int charLoc; string currentWords; CS = 0; //bool newLine = false; // open the input file Input.txt ifstream inFile("Input.txt"); // if the file failed to open, notify the user. if(inFile.is_open()) { getline(inFile, currentWords); if(currentWords.empty() == false) { do { charLoc = currentWords.find(","); Words[CS] = currentWords.substr(0, charLoc); currentWords = currentWords.substr(charLoc + 1, currentWords.length()); CS++; }while(CS < AS && currentWords.length() > 3); } /* // as long as there is a 'word' to read from the file, loop. while(inFile >> currentWord && CS < AS -1) { cout << currentWord; CS++; } */ // Close the input file inFile.close(); } else //if the file did open, process the file. { cout << "error opening file"; } } void FileSystem::ListTestArray() { system("cls"); for(int i = 0; i < CS; i++) { cout << i << " " << Words[i] << endl; } system("PAUSE"); system("cls"); } void FileSystem::TestMakeDirs() { //load the array with random words openInFile(); if(CS > 0) { // make a directory for each random word for(int i = 0; i <=CS; i++) { cout << "Creating dir: " << Words[i] << endl; CurrentDir->Create(Words[i]); } } // display the directories and files CurrentDir->SMPrint(); } ************************************ File header: ************************************** #ifndef File_h #define File_h #include <cstdlib> #include <iostream> #include <string> //using namespace std; class File { private: std::string Name, Extension; /* SplitName Inputs: FN (String) Output: None Notes: Used to split a string based on the '.' character. This allows the Name and Extension to be found. */ void SplitName(string FN); public: /* Constructor Inputs: FullName Outputs: None Notes: Takes in the full name (name + extension) splits it. */ File(string FullName); /* Constructor Inputs: FullName Outputs: None Notes: Takes in the full name (name + extension) splits it. */ File(); /* Copy Constructor Due to the requirement that no files in the same directory can have the same name, and the fact there is no copy required for this assignment the copy constructor is not required. */ /* Copy Assignment Inputs: F (file) Outputs: bool */ bool operator=(const File *F); File & File: /* Destructor Because there are no pointers used the default destructor is fine. No destructor was created for 'file' */ /* GetName Inputs: None Outputs Name (minus extension) */ string GetName(); /* GetExtension Inputs: None Outputs: File Extension */ string GetExtension(); /* GetFileName Inputs: None Output: full file name (name and extension) */ string GetFileName(); /* Inputs: None Outputs: prints to screen full file name (name and extension) */ void Print(); /* operator == Inputs: File F Outputs: bool Notes: If the file.Name and file.Extension are equal the files are equal if either is not equal, the files are not equal. */ bool operator==(const File & F); /* operator== Input: FN (string file name) Output: bool Notes: returns true if the file uses the same name as FN */ bool operator==(string FN); /* operator < Inputs: File F Outputs: bool Notes: If the full file name is < the 'other' file name True. */ bool operator<(const File & F); /* operator < Inputs: FN (string file name) Outputs: bool Notes: If the full file name is < the 'other' file name True. */ bool operator<(string FN); /* operator > Inputs: File F Outputs: bool */ bool operator>(const File & F); /* operator > Inputs: FN (string file name) Outputs: bool */ bool operator>(string FN); /* ValidName Input: N (name) Output: bool Note: used to determine if a name is valid for a file. No spaces and a dot. */ bool ValidName(string &N); }; #endif ************************ File Code: **************************** #include "File.h" #include <iostream> #include <cstdlib> #include <string> //using namespace std; /* Constructor */ File::File(string FullName) { SplitName(FullName); } File::File() { Name = ""; Extension = ""; } //GetFileName string File::GetFileName() { return (Name + "." + Extension); } // Copy Assignment bool File: { if(F->Name != "" && F->Extension != "") { Name = F->Name; Extension = F->Extension; return true; } else return false; } File & File: { if(F.Name != "" && F.Extension != "") { Name = F.Name; Extension = F.Extension; } } /* SplitName */ void File::SplitName(string FN) { int charLoc; // character location charLoc = FN.find('.'); // if there is no 'dot' then the Name is the Fullname (no extension) if(charLoc == -1) { Name = FN; Extension = ""; } else //There is a dot so set the Name and Extension values { Name = FN.substr(0, charLoc); Extension = FN.substr(charLoc + 1, FN.length()); } } bool File::ValidName(string &N) { int charLoc; // character location SplitName(N); // there must be a 'name' portion if(Name == "") return false; if(Extension == "") return false; charLoc = N.find(' '); // search for a space in the name anywhere if(charLoc == -1) // no spaces return true; else return false; } /* GetName */ string File::GetName() { return Name; } /* GetExtension */ string File::GetExtension() { return Extension; } /* */ void File: { cout << Name << '.' << Extension; } /* operator== */ bool File: { if(Name != F.Name) return false; if(Extension != F.Extension) { return false; } else { return true; } } /* operator< */ bool File: { //if the file Name is >, then false if(Name > F.Name) return false; //if the file Name is <, then true if(Name < F.Name) return true; //if we got to here then the file Name properties are equal if(Extension < F.Extension) // this extension is < other, then true { return true; } else // this extension is NOT < other, then false { return false; } } bool File: { if(GetFileName() > FN) return false; if(GetFileName() == FN) return false; if(GetFileName() < FN) return true; } /* operator> */ bool File: { if(Name < F.Name) return false; if(Name > F.Name) return true; // if we got to here the names are equal if(Extension > F.Extension) return true; else return false; } bool File: { if(GetFileName() < FN) return false; if(GetFileName() == FN) return false; if(GetFileName() > FN) return true; } ************************** Main: ****************************** #include <cstdlib> #include <iostream> //#include "File.h" //#include "Directory.h" #include "FileSystem.h" using namespace std; int main(int argc, char *argv[]) { /*string FN; Directory dir("/"); bool result; for(int i = 0; i <= 6; i++) { result = dir.MKFile(); } dir.SMPrint(); */ FileSystem FS; FS.main(); // cout << "Find a file position; enter file name: "; //getline(cin, FN); //dir.FindFile(dir.Files, 0, dir.FileCount -1); system("PAUSE"); return EXIT_SUCCESS; } ************************** Oh; a comment on the std:: - the teaching assistant seems to favour NOT using std:: so that's the way I will go for now. He's got to mark it. Best to keep it to what he likes. By the way... are you independantly wealthy or just very generous with your time?? Also; is there a way to get the system to email me if there is a reply? > Work on those things a little, and come back. > > Nobody ever said C++ was easy! Hang in there! > -- > Bob R > POVrookie |
|
|
|
|
|||
|
|||
| sandy@murdocks.on.ca |
|
sandy@murdocks.on.ca
Guest
Posts: n/a
|
wrote: > BobR wrote: > Directory::~Directory(){ > delete[] Files; > // and since your vector holds pointers to 'new' objects. > for( size_t i(0); i < Directories.size(); ++i ){ > delete Directories.at( i ); > } > } // Dtor This one is much shorter. I have noticed in code on the net a lot of people use 'size_t' with their vector. Is that a specific command or is it the same as: for(int i = 0; i < Directories.size(); i++) if so, why do people use the size_t? (I used int i and it SEEMS to work) |
|
|
|
|
|||
|
|||
| sandy@murdocks.on.ca |
|
BobR
Guest
Posts: n/a
|
wrote in message ... > >> BobR wrote: >> Directory::~Directory(){ >> delete[] Files; >> // and since your vector holds pointers to 'new' objects. >> for( size_t i(0); i < Directories.size(); ++i ){ >> delete Directories.at( i ); >> } >> } // Dtor > >This one is much shorter. Checking out your other post. It'll get shorter. Post later. > >I have noticed in code on the net a lot of people use 'size_t' with >their vector. Is that a specific command or is it the same as: for(int >i = 0; i < Directories.size(); i++) > >if so, why do people use the size_t? std::size_t is a typedef of an unsigned integral. std::vector::size_type (returned by .size() ) is also an unsigned type. > >(I used int i and it SEEMS to work) You don't have your compiler warning level up high enough or you would be seeing warnings like "comparing signed with unsigned". Why compare red dogs with blue dogs? If you are using Dev-C++(MinGW), put -Wall -W in the compiler flags. (many more in the GCC docs "GCC Command Options" sub"Options to Request or Suppress Warnings".). Are you brave? { int sz(-1); std::vector<int> BigV( sz ); std::cout<<BigV.size(); } // don't want to keep that puppy around long! -- Bob R POVrookie |
|
|
|
|
|||
|
|||
| BobR |
|
sandy@murdocks.on.ca
Guest
Posts: n/a
|
BobR wrote: > wrote in message ... > > > >> BobR wrote: > >> Directory::~Directory(){ > >> delete[] Files; > >> // and since your vector holds pointers to 'new' objects. > >> for( size_t i(0); i < Directories.size(); ++i ){ > >> delete Directories.at( i ); > >> } > >> } // Dtor > > Actually I had envisioned having to write something that would make calls on each sub-directory and it's subdirectories etc. to cascade through calling the destructor; but of course I don't. Since this destroys an instance of a Directory, that destruction calls that instance's destructor. It is pretty simple. (much better than what I had thought.) I tend to try to get my code working first, then try to figure out the destructors etc. I sort of 'build as I need' for things like copy constructors etc. Then if I run out of time I can hand in a working program with problems, not a non-working program. > >This one is much shorter. Yes; I have started some of that myself already. My overloaded operators are now shorter, those based on string compares are now just like this: bool Directory: { return Name < D.Name; } rather than with if then statements etc. > > Checking out your other post. It'll get shorter. Post later. > > > > >I have noticed in code on the net a lot of people use 'size_t' with > >their vector. Is that a specific command or is it the same as: for(int > >i = 0; i < Directories.size(); i++) > > > >if so, why do people use the size_t? > > std::size_t is a typedef of an unsigned integral. std::vector::size_type > (returned by .size() ) is also an unsigned type. > Hmmm... Okay. I will stick with the convention. > > > >(I used int i and it SEEMS to work) > > You don't have your compiler warning level up high enough or you would be > seeing warnings like "comparing signed with unsigned". Why compare red dogs > with blue dogs? > If you are using Dev-C++(MinGW), put -Wall -W in the compiler flags. > (many more in the GCC docs "GCC Command Options" sub"Options to Request or > Suppress Warnings".). > > Are you brave? > { > int sz(-1); > std::vector<int> BigV( sz ); > > std::cout<<BigV.size(); > } // don't want to keep that puppy around long! > > -- > Bob R > POVrookie |
|
|
|
|
|||
|
|||
| sandy@murdocks.on.ca |
|
sandy@murdocks.on.ca
Guest
Posts: n/a
|
Just wanted to let you know that I created a new, shorter specific posting about sorting the vector elsewhere. Sort a Vector of Pointers to an object, based on objects properties It wasn't really this topic/thread even though it's still my problem. I think that was the correct thing to do! |
|
|
|
|
|||
|
|||
| sandy@murdocks.on.ca |
|
|
|
| |
![]() |
| Thread Tools | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| pointers, pointers, pointers... | cerr | C Programming | 12 | 04-07-2011 11:17 PM |
| access object in array of pointers to dynamic array of class complex | jccorreu@gmail.com | C++ | 2 | 05-20-2006 05:08 AM |
| "stringObj == null" vs "stringObj.equals(null)", for null check?? | qazmlp1209@rediffmail.com | Java | 5 | 03-29-2006 10:37 PM |
| Can a static array contain a dynamic array of pointers? | Peter B. Steiger | C Programming | 8 | 04-26-2004 03:07 AM |
| Unexpected initial null in return from split() | Craig M. Votava | Perl Misc | 3 | 01-30-2004 08:14 PM |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc..
SEO by vBSEO ©2010, Crawlability, Inc. |




