#include <iostream>
#include <string>
#include <stdio.h> // defines FILENAME_MAX for current directory
#include <algorithm>
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
static const char separator = '/';
#else
#include <unistd.h>
#define GetCurrentDir getcwd
static const char separator = '\\';
#endif
//Templates
std::string getTruePath(std::string path);
std::string normalizePath(std::string path);
int initialSlashCount(std::string path);
/******************************************************
* MAIN
* Prompts the user for two file paths. The paths are
* compared, and the user is informed whether they are
* homographs.
*****************************************************/
int main()
{
std::string path1;
std::string path2;
std::cout << "Insert first path" << std::endl;
std::cin >> path1;
std::cout << "Insert second path" << std::endl;
std::cin >> path2;
//Normalize strings acorting to operating system
path1 = normalizePath(path1);
path2 = normalizePath(path2);
std::cout << "The paths are "
//If both cannons are the same, they are homomograph
<< ((getTruePath(path1) == getTruePath(path2)) ? "" : "NOT")
<< " homographs" << std::endl;
return 0;
}
/****************************************************
* GETTRUEPATH
* Applies the navigation instructions signified by
* ".", "..", and "~" symbols. "." means the current
* directory, ".." means the parent directory,
* and "~" means the home directory.
***************************************************/
std::string getTruePath(std::string path)
{
char cCurrentPath[FILENAME_MAX];
GetCurrentDir(cCurrentPath, FILENAME_MAX);
std::string sDir(cCurrentPath); //The default directory
//normalize current directory
sDir = normalizePath(sDir);
int slashCount = initialSlashCount(sDir);
for (int i = 0; i < path.length(); i++)
{
if (i == 0 && path[0] != separator)
{
path = separator + path;
slashCount--;
}
if (path[i] == '.' || path[i] == '~')
{
//Here is when we find ../ (parent operator)
if (path[i + 1] == '.')
{
i += 2;
int tSlash = 0;
std::string tDir = "";
int dirIterator = 0;
while (tSlash < slashCount)
{
if (sDir[dirIterator] == separator)
tSlash++;
tDir += sDir[dirIterator++];
}
sDir = tDir;
//decrement directories
slashCount--;
}
else if (path[i + 1] == separator || path[i] == '~') //The path begins with the current directory
{
i++;
}
continue; //Next for iteration
}
if (path[i] == separator)
slashCount++;
sDir += path[i];
}
return sDir;
}
/*************************************************
* NORMALIZEPATH
* Canonicalizes the file paths by converting
* all letters to lowercase and converting
* slash symbols to a unified format, since slash
* symbols in a file path are different depending
* on the operating system.
* INPUT: String: file path
* OUTPUT: String: normalize lowercase path.
************************************************/
std::string normalizePath(std::string path)
{
for (int i = 0; i < path.length(); i++)
{
if (path[i] == '/' || path[i] == '\\')
path[i] = separator;
}
//Transforming to lowercase
std::transform(path.begin(), path.end(), path.begin(),
[](unsigned char c)
{ return std::tolower(c); });
return path;
}
/**********************************************
* INITIALSLASHCOUNT
* Returns the number of slash symbols used in
* the file path.
* INPUT: String: file path
* OUTPUT: Number of slashes/directories.
*********************************************/
int initialSlashCount(std::string path)
{
int count = 0;
for (int i = 0; i < path.length(); i++)
{
if (path[i] == separator)
count++;
}
return count;
}
Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++ and start coding!
OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter name:";
getline (cin, name);
cout << "Hello " << name;
return 0;
}
C++ is a widely used middle-level programming language.
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression){
case value1:
// code
break; // optional
case value2:
// code
break; // optional
......
default:
code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
// code
}