Starting work on #7.
This commit is contained in:
		
							
								
								
									
										1
									
								
								2022/7/Makefile
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								2022/7/Makefile
									
									
									
									
									
										Symbolic link
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					../starter/Makefile
 | 
				
			||||||
							
								
								
									
										1013
									
								
								2022/7/data.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1013
									
								
								2022/7/data.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										180
									
								
								2022/7/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								2022/7/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
				
			|||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <set>
 | 
				
			||||||
 | 
					#include <stack>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<std::string> SplitStr(std::string str, const std::string &delim)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::vector<std::string> rtn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for(auto split = str.find(delim); split != std::string::npos; split = str.find(delim))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							rtn.push_back(str.substr(0, split));
 | 
				
			||||||
 | 
							str = str.substr(split + delim.size()); // chop off beginning
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(str.size())
 | 
				
			||||||
 | 
							rtn.push_back(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rtn;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class File {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						File(const std::string &set_filename, unsigned long set_size)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								this->size = set_size;
 | 
				
			||||||
 | 
								this->filename = set_filename;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual ~File()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const std::string& Filename() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return filename;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						virtual unsigned long Size() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return size;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						unsigned long size;
 | 
				
			||||||
 | 
						std::string filename;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Folder : public File {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						Folder(const std::string &filename)
 | 
				
			||||||
 | 
							: File(filename, 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned long Size() const override
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								unsigned long size = 0;
 | 
				
			||||||
 | 
								for(const auto *file : files)
 | 
				
			||||||
 | 
									size += file->Size();
 | 
				
			||||||
 | 
								return size;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void AddFile(const std::string &filename,
 | 
				
			||||||
 | 
						             unsigned long size)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// make sure the file doesn't already exist:
 | 
				
			||||||
 | 
								if(std::find_if(files.begin(), files.end(),
 | 
				
			||||||
 | 
								                [&](const File *file) {
 | 
				
			||||||
 | 
									                return file->Filename() == filename;
 | 
				
			||||||
 | 
								                }) != files.end())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									std::cerr << "Folder \"" << this->Filename() << "\" already contains "
 | 
				
			||||||
 | 
									          << "the file \"" << filename << "\"." << std::endl;
 | 
				
			||||||
 | 
									exit(-1);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// increment this folder's size total:
 | 
				
			||||||
 | 
								this->size += size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// add the file:
 | 
				
			||||||
 | 
								files.push_back(new File(filename, size));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void AddFolder(const std::string &name)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if(std::find_if(files.begin(), files.end(),
 | 
				
			||||||
 | 
								                [&](const File *file) {
 | 
				
			||||||
 | 
									                return file->Filename() == name;
 | 
				
			||||||
 | 
								                }) != files.end())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									std::cout << "NOTE: Folder \"" << this->Filename() << "\" already contains "
 | 
				
			||||||
 | 
									          << "the subfolder \"" << name << "\"." << std::endl;
 | 
				
			||||||
 | 
									// exit(-1);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								files.push_back(new Folder(name));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const std::vector<File*>& Files() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return files;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						std::vector<File*> files;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::ifstream ifs("data.txt");
 | 
				
			||||||
 | 
						if(!ifs.is_open())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::cerr << "Missing data.txt." << std::endl;
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Folder root("/");
 | 
				
			||||||
 | 
						std::stack<Folder*> dir_stack;
 | 
				
			||||||
 | 
						dir_stack.push(&root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for(std::string line; std::getline(ifs, line); )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if(line == "")
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(line.starts_with("$ ls"))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							else if(line.starts_with("$ cd"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto to = line.substr(5);
 | 
				
			||||||
 | 
								if(to == "/")
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									while(dir_stack.size() > 1)
 | 
				
			||||||
 | 
										dir_stack.pop();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if(to == "..")
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if(dir_stack.size() > 1)
 | 
				
			||||||
 | 
										dir_stack.pop();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									auto existing = std::find_if(dir_stack.top()->Files().begin(),
 | 
				
			||||||
 | 
								                     dir_stack.top()->Files().end(),
 | 
				
			||||||
 | 
								                     [&to](const File *f){
 | 
				
			||||||
 | 
									                     return f->Filename() == to;
 | 
				
			||||||
 | 
								                     });
 | 
				
			||||||
 | 
									if(existing != dir_stack.top()->Files().end()) // found!
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										// Check to see if it's a folder, first:
 | 
				
			||||||
 | 
										Folder *folder = dynamic_cast<Folder*>(*existing);
 | 
				
			||||||
 | 
										if(folder)
 | 
				
			||||||
 | 
											dir_stack.push(folder);
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											std::cerr << (*existing)->Filename() << " is a file, not a folder."
 | 
				
			||||||
 | 
											          << std::endl;
 | 
				
			||||||
 | 
											exit(-3);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										std::cerr << "could not navigate to \"" << to << "\" from \""
 | 
				
			||||||
 | 
										          << dir_stack.top()->Filename() << "\"." << std::endl;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if(line.starts_with("dir "))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								dir_stack.top()->AddFolder(line.substr(4));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto values = SplitStr(line, " ");
 | 
				
			||||||
 | 
								dir_stack.top()->AddFile(values[1], std::atol(values[0].c_str()));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user