Data Structure only C++ Write a program that will simulate a Unix File System. T
ID: 3721208 • Letter: D
Question
Data Structure only C++
Write a program that will simulate a Unix File System. This program will use a tree to represent the file system. It should provide, at a minimum, the following functionality to the user: mkdir, touch, cd, ls, and exit. When this program runs it should display a welcome prompt and then wait for input from the user. The user should be then be able type in their commands. The idea is to simulate the command prompt of windows or the shell prompt of Linux. Your program should feel similar to either of these shells. mkdir – This should create a new “directory” in the current directory with ‘dirname’ as it’s name. touch – This should create a new “file” in the current directory with ‘filename’ as it’s name. cd – This should change the current directory to the directory specified by ‘path’. It should be able to accept both relative and absolute paths. A relative path starts with a ‘/’ and describes a path from the root. A relative path will start with a ‘.’ and describes a path from the current directory. ‘..’ indicates the parent directory. ‘.’ Indicates the current directory. Paths should use a ‘/’ to separate folders in the path. For example ‘../home/fconlon’. A ‘/’ by itself indicates the root directory. If a user attempts to cd to a file or a directory that does not exist an error message should be displayed, and the program should continue to run. ls – This should display all of the files and directories in the directory specified by ‘path’. If not path is specified then it should display all the files and directories in the current directory. This command should first display all the directories in the current directory in alphabetical order the display all of the files in the current directory in alphabetical order. ‘path’ should follow the same conventions for the ‘path’ argument from cd. It should display the same errors under the same conditions as cd. Exit – This should exit the program. Don’t forget to clear any memory that you allocated.
Explanation / Answer
#include <bits/stdc++.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
using namespace std;
// Case insensitive string comparison
bool caseInsensitiveStrCompare(string s1, string s2) {
int i;
for(i = 0; i < s1.size() && i < s2.size(); i++) {
if (tolower(s1[i]) < tolower(s2[i])) return true;
else if (tolower(s1[i]) > tolower(s2[i])) return false;
}
// s1 is smaller than s2
if (i < s2.size()) {
return true;
}
// s2 is smaller than s1
else if (i < s1.size()) {
return false;
}
return true;
}
int main() {
cout<<"Welcome! ";
string command;
while (true) {
// Print the terminal text
char cwd[1024];
getcwd(cwd, 1024);
cout<<cwd<<"> ";
// Get the command from the user
getline(cin, command);
if (command.size() < 1) continue;
// Split the string using spaces
istringstream iss(command);
vector<string> words(istream_iterator<string>{iss}, std::istream_iterator<string>());;
// mkdir
if (words[0] == "mkdir") {
// if no directory name mentioned
if (words.size() < 2) {
cout<<"mkdir: missing operand ";
continue;
}
// print error if fails
if (mkdir(words[1].c_str(), 0777) < 0) {
if (errno == EACCES) cout<<"mkdir failed Error " <<errno<<": Permission denied"<<endl;
else if (errno == EEXIST) cout<<"mkdir failed Error " <<errno<<": directory is already present"<<endl;
}
}
// touch
else if (words[0] == "touch") {
// if no filename mentioned
if (words.size() < 2) {
cout<<"mkdir: missing file operand ";
continue;
}
// create a file in append mode and close it
ofstream outfile;
outfile.open(words[1], ios_base::app);
outfile.close();
}
// cd
else if (words[0] == "cd") {
// if no directory mentioned
if (words.size() < 2) {
cout<<"cd: missing operand ";
continue;
}
// if cd fails
if (chdir(words[1].c_str()) < 0) {
cout<<"Invalid directory "<<words[1]<<endl;
}
}
// ls
else if (words[0] == "ls") {
// Set the directory for ls
string dir = cwd;
if (words.size() > 1) dir = words[1];
// Check if the directory is present
DIR *dp = opendir(dir.c_str());;
if(dp == NULL) {
cout<<"Invalid directory "<<dir<<endl;
continue;
}
// Read while files are present and append to a vector
vector<string> filenames;
struct dirent *dirp = readdir(dp);
while (dirp!= NULL) {
// Skip hidden directories and . and ..
if (dirp->d_name[0] != '.') filenames.push_back(dirp->d_name);
dirp = readdir(dp);
}
// Sort and print the filenames
sort(filenames.begin(), filenames.end(), caseInsensitiveStrCompare);
for (int i = 0; i < filenames.size(); i++) {
cout<<filenames[i]<<endl;
}
// Close the directory
closedir(dp);
}
// exit
else if (words[0] == "exit") {
break;
}
// Invalid command
else {
cout<<"Invalid command "<<words[0]<<endl;
}
}
return 0;
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.