Obtener un nombre de directorio de un nombre de archivo


Tengo un nombre de archivo (C:\folder\foo.txt) y necesito recuperar el nombre de la carpeta (C:\folder) en C++no administrado. En C# haría algo como esto:

string folder = new FileInfo("C:\folder\foo.txt").DirectoryName;

¿Hay una función que se pueda usar en C++ no administrado para extraer la ruta del nombre del archivo?

Author: Jon Tackabury, 2010-06-18

11 answers

Existe una función estándar de Windows para esto, PathRemoveFileSpec. Si solo admite Windows 8 y versiones posteriores, es muy recomendable usar PathCchRemoveFileSpec en su lugar. Entre otras mejoras, ya no está limitado a MAX_PATH (260) caracteres.

 23
Author: Andreas Rejbrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-31 16:53:30

Usando Boost.Sistema de archivos:

boost::filesystem::path p("C:\\folder\\foo.txt");
boost::filesystem::path dir = p.parent_path();
 132
Author: AraK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 17:11:51

Ejemplo de http://www.cplusplus.com/reference/string/string/find_last_of/

// string::find_last_of
#include <iostream>
#include <string>
using namespace std;

void SplitFilename (const string& str)
{
  size_t found;
  cout << "Splitting: " << str << endl;
  found=str.find_last_of("/\\");
  cout << " folder: " << str.substr(0,found) << endl;
  cout << " file: " << str.substr(found+1) << endl;
}

int main ()
{
  string str1 ("/usr/bin/man");
  string str2 ("c:\\windows\\winhelp.exe");

  SplitFilename (str1);
  SplitFilename (str2);

  return 0;
}
 51
Author: corsiKa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 17:07:08

Según cppreference.com, existe soporte de biblioteca de encabezado experimental para C++17 / 1z con la clase std::experimental::filesystem::path usando el método parent_path.

#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
int main()
{
    for(fs::path p : {"/var/tmp/example.txt", "/", "/var/tmp/."})
        std::cout << "The parent path of " << p
                  << " is " << p.parent_path() << '\n';
}

Posible salida:

The parent path of "/var/tmp/example.txt" is "/var/tmp"
The parent path of "/" is ""
The parent path of "/var/tmp/." is "/var/tmp"
 9
Author: Alessandro Jacopson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-08 17:22:31

¿Por qué tiene que ser tan complicado?

#include <windows.h>

int main(int argc, char** argv)         // argv[0] = C:\dev\test.exe
{
    char *p = strrchr(argv[0], '\\');
    if(p) p[0] = 0;

    printf(argv[0]);                    // argv[0] = C:\dev
}
 8
Author: toster-cx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-07 22:58:49

Use boost::filesystem. Se incorporará al siguiente estándar de todos modos, por lo que también puede acostumbrarse a él.

 5
Author: Crazy Eddie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 17:11:23

_splitpath es una buena solución de CRT.

 2
Author: Ofek Shilon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 17:39:42

Estoy tan sorprendido de que nadie haya mencionado la forma estándar en Posix

Por favor use basename / dirname construcciones.

Nombre de base del hombre

 1
Author: Utkarsh Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 22:40:22
 auto p = boost::filesystem::path("test/folder/file.txt");
 std::cout << p.parent_path() << '\n';             // test/folder
 std::cout << p.parent_path().filename() << '\n';  // folder
 std::cout << p.filename() << '\n';                // file.txt

Es posible que necesite p.parent_path().filename() para obtener el nombre de la carpeta principal.

 1
Author: srbcheema1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-27 16:41:18

El C++ estándar no hará mucho por usted en este sentido, ya que los nombres de ruta son específicos de la plataforma. Puede analizar manualmente la cadena (como en la respuesta de glowcoder), usar las instalaciones del sistema operativo (por ejemplo, http://msdn.microsoft.com/en-us/library/aa364232 (v=VS.85). aspx), o probablemente el mejor enfoque, puede usar una biblioteca de sistemas de archivos de terceros como boost::filesystem.

 0
Author: Cogwheel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 17:09:55

Simplemente use esto: ExtractFilePath (your_path_file_name)

 -3
Author: fxPiotr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-10 02:18:27