path


A path is a sequence of steps through a file system that leads to a file system entry. The following are types of paths.

Each component of a path is identified by a term. The following table identifies these terms using both UNIX and PC examples.
 
Term Description Value from Example

Directory

Portion of the path excluding the filename and the drive ID or UNC.

/usr/lib/tmp/

\windows\system\

Filename

Portion of the path excluding the directory and the drive ID or UNC.

libc.a.old

win.ini

Head

First component of the directory.

usr

Windows

Tail

Last component of the directory.

tmp

system

Base

Filename minus the extension.

libc.a

win

Extension

All characters to the right of the last dot (.) in the filename.

old

ini


os_path
contains functions to access these components, as well as to test various aspects of a path. In addition, you can use operator[] to access individual components of a path. To obtain the head of a path, use operator[] with index 0.

The various ways to construct a path are listed below.

The following example illustrates all of these techniques. Note that the double backslash ("\\") is required by compilers to include a backslash in source. The compiler interprets the first backslash as a special character.

Example <ospace/file/examples/path1.cpp>
#include <iostream>
#include <ospace/file.h>

void
main()
  {
  os_file_toolkit initialize;

  os_path path1;
  os_path path2( "\\windows\\win.ini" ); // absolute filepath
  os_path path3( "\\windows", "" ); // absolute dirpath
  os_path path4( "windows\\win.ini" ); // relative dirpath
  os_path path5( "\\windows", "win.ini" ); // absolute filepath
  os_path path6( "win.ini" ); // filename
  cout << "path1 = " << path1 << endl;
  cout << "path2 = " << path2 << endl;
  cout << "path3 = " << path3 << endl;
  cout << "path4 = " << path4 << endl;
  cout << "path5 = " << path5 << endl;
  cout << "path6 = " << path6 << endl;
  }

path1 =
path2 = \windows\win.ini
path3 = \windows\
path4 = windows\win.ini
path5 = \windows\win.ini
path6 = win.ini

The File<ToolKit> source code and documentation adopt the following UNIX and PC conventions for naming path-related variables.
 
Name Meaning Examples

filename

Name of a file.

file.txt

win.ini

filepath

Name of a file and optional leading directory component.

/usr/lib/file.txt

\windows\temp\file.txt

dirpath

Directory path, which cannot include a filename, but which optionally includes a leading directory component. Always ends in a directory separator ("\" for UNIX and "/" for PC).

/usr/lib/

\windows\temp\

path

File or directory, which optionally includes a leading directory component.

/usr/lib/file.txt

temp\file.txt


Due to automatic conversion operators, once a path is constructed it can be used whenever a const char* or const string& is expected.

Although a correlation exists between paths that end with an extension and paths that refer to regular files, there are exceptions. For example, the path /usr/tmp/a.b/ could refer to a directory called a.b or to a file called a.b in the directory /usr/tmp. The following example constructs both kinds of paths and shows how each kind of path is interpreted.

Example <ospace/file/examples/path2.cpp>
#include <iostream>
#include <ospace/file.h>

void
display( os_path& path )
  {
  cout << "path = " << path << endl;
  cout << "path.directory() = " << path.directory() << endl;
  cout << "path.filename() = " << path.filename() << endl;

  int levels = path.levels();
  cout << "levels = " << levels << endl;
  for (int i = 0; i < levels; i++)
    cout << "  path[ " << i << " ] = " << path[ i ] << endl;

  cout << "path.head() = " << path.head() << endl;
  cout << "path.tail() = " << path.tail() << endl;
  cout << "path.base() = " << path.base() << endl;
  cout << "path.extension() = " << path.extension() << endl;
  cout << "path.file_path() = " << path.file_path() << endl;
  cout << "path.directory_path() = " << path.directory_path()<< endl;
  cout << "path.relative() = " << path.relative() << endl;
  cout << "path.has_directory() = " << path.has_directory() << endl;
  cout << "path.has_extension() = " << path.has_extension() << endl;
  cout << endl;
  }

void
main()
  {
  os_file_toolkit initialize;

  // Construct path to file named "/tmp/user/scratch.txt"
  os_path path1;
  path1.path_separator( '/' );
  path1 = "/tmp/user/scratch.txt";
  display( path1 );

  // Construct path to directory named "\windows\temp\scratch.txt".
  os_path path2;
  path2.path_separator( '\\' );
  path2 = "\\windows\\temp\\scratch.txt";
  display( path2 );
  }

path = /tmp/user/scratch.txt
path.directory() = /tmp/user/
path.filename() = scratch.txt
levels = 2
  path[ 0 ] = tmp
  path[ 1 ] = user
path.head() = tmp
path.tail() = user
path.base() = scratch
path.extension() = txt
path.file_path() = 1
path.directory_path() = 0
path.relative() = 0
path.has_directory() = 1
path.has_extension() = 1

path = \windows\temp\scratch.txt
path.directory() = \windows\temp\
path.filename() = scratch.txt
levels = 2
  path[ 0 ] = windows
  path[ 1 ] = temp
path.head() = windows
path.tail() = temp
path.base() = scratch
path.extension() = txt
path.file_path() = 1
path.directory_path() = 0
path.relative() = 0
path.has_directory() = 1
path.has_extension() = 1

The following example constructs a path and then changes its components one at a time. When the base of a filename with an extension is set to an empty string, the filename is interpreted as a special dot file and its extension is considered empty.

Example <ospace/file/examples/path3.cpp>
#include <iostream>
#include <ospace/file.h>

void
main()
  {
  os_file_toolkit initialize;

  os_path path;
  path.path_separator( '\\' );
  path = "\\windows\\system\\ole2.dll";
  cout << "path = " << path << endl;

  path.head( "x" );
  cout << "path = " << path << endl;

  path.directory( "a\\b\\c" );
  cout << "path = " << path << endl;

  path.base( "y" );
  cout << "path = " << path << endl;

  path.extension( "drv" );
  cout << "path = " << path << endl;

  path.extension( "" );
  cout << "path = " << path << endl;

  path.extension( "lib" );
  cout << "path = " << path << endl;
  cout << "path.has_extension() = " << path.has_extension() << endl;

  path.base( "" );
  cout << "path = " << path << endl;
  cout << "path.filename() = " << path.filename() << endl;
  cout << "path.base() = " << path.base() << endl;
  cout << "path.extension() = " << path.extension() << endl;
  cout << "path.has_extension() = " << path.has_extension() << endl;

  path.filename( "a.b" );
  cout << "path = " << path << endl;

  path.section( 1, "library" );
  cout << "path = " << path << endl;

  path.path_separator( '/' );
  cout << "path = " << path << endl;
  }

path = \windows\system\ole2.dll
path = \x\system\ole2.dll
path = \a\b\c\ole2.dll
path = \a\b\c\y.dll
path = \a\b\c\y.drv
path = \a\b\c\y
path = \a\b\c\y.lib
path.has_extension() = 1
path = \a\b\c\.lib
path.filename() = .lib
path.base() = .lib
path.extension() =
path.has_extension() = 0
path = \a\b\c\a.b
path = \a\library\c\a.b
path = /a/library/c/a.b

You can alter several aspects of a path in a single statement by cascading any combination of the following functions.

cd() operates only on the path's directory component and works like the shell counterpart. In addition, become_simplified() converts a path to its simplest form and become_relative_to() recasts a directory in relation to another directory path. The cd() and become_relative_to() functions automatically simplify their resulting paths.

Example <ospace/file/examples/path4.cpp>
#include <iostream>
#include <ospace/file.h>

void
main()
  {
  os_file_toolkit initialize;

  os_path path( "/./usr/../usr/lib/tmp/../tmp/libc.a" );
  cout << "path = " << path << endl;

  path.become_simplified();
  cout << "path = " << path << endl;

  path.cd( ".." ).base( "file" ).extension( "cxx" );
  cout << "path = " << path << endl;

  path.cd( "bin" );
  cout << "path = " << path << endl;

  path.become_relative_to( "/usr" );
  cout << "path = " << path << endl;

  path.cd( "/" );
  cout << "path = " << path << endl;
  }

path = /./usr/../usr/lib/tmp/../tmp/libc.a
path = /usr/lib/tmp/libc.a
path = /usr/lib/file.cxx
path = /usr/lib/bin/file.cxx
path = lib/bin/file.cxx
path = /file.cxx


Copyright©1994-2026 Recursion Software LLC
All Rights Reserved - For use by licensed users only.