#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;
}
 
by

C++ Online Compiler

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!

Read inputs from stdin

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;
}

About C++

C++ is a widely used middle-level programming language.

  • Supports different platforms like Windows, various Linux flavours, MacOS etc
  • C++ supports OOPS concepts like Inheritance, Polymorphism, Encapsulation and Abstraction.
  • Case-sensitive
  • C++ is a compiler based language
  • C++ supports structured programming language
  • C++ provides alot of inbuilt functions and also supports dynamic memory allocation.
  • Like C, C++ also allows you to play with memory using Pointers.

Syntax help

Loops

1. If-Else:

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.

2. Switch:

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;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement){  
  //code  
} 

4. While:

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 
}  

5. Do-While:

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); 

Functions

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.

How to declare a Function:

return_type function_name(parameters);

How to call a Function:

function_name (parameters)

How to define a Function:

return_type function_name(parameters) {  
 // code
}