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