Получить имя файла из пути - PullRequest
69 голосов
/ 15 декабря 2011

Какой самый простой способ получить имя файла по пути?

string filename = "C:\\MyDirectory\\MyFile.bat"

В этом примере я должен получить «MyFile».без расширения.

Ответы [ 19 ]

5 голосов
/ 18 октября 2013

C ++ 11 вариант (навеянный версией Джеймса Канзе) с равномерной инициализацией и анонимной встроенной лямбдой.

std::string basename(const std::string& pathname)
{
    return {std::find_if(pathname.rbegin(), pathname.rend(),
                         [](char c) { return c == '/'; }).base(),
            pathname.end()};
}

Хотя расширение файла не удаляется.

4 голосов
/ 24 марта 2016

это единственное, что на самом деле наконец-то сработало для меня:

#include "Shlwapi.h"

CString some_string = "c:\\path\\hello.txt";
LPCSTR file_path = some_string.GetString();
LPCSTR filepart_c = PathFindFileName(file_path);
LPSTR filepart = LPSTR(filepart_c);
PathRemoveExtension(filepart);

в значительной степени то, что предложил Скримсли, но не работает с wchar_t *, VS Enterprise 2015

_splitpath также работает, но мне не нравится угадывать, сколько символов char [?] Мне понадобится; некоторые люди, вероятно, нуждаются в этом контроле, я думаю.

CString c_model_name = "c:\\path\\hello.txt";
char drive[200];
char dir[200];
char name[200];
char ext[200];
_splitpath(c_model_name, drive, dir, name, ext);

Я не верю, что для _splitpath нужны были какие-либо включения. Никакие внешние библиотеки (например, boost) не требовались ни для одного из этих решений.

3 голосов
/ 15 декабря 2011

Я бы сделал это с помощью ...

Поиск назад от конца строки, пока не найдете первую обратную косую черту / прямую косую черту.

Затем поиск назад от концаСтрока, пока вы не найдете первую точку (.)

Затем у вас есть начало и конец имени файла.

Simples ...

2 голосов
/ 15 декабря 2011
m_szFilePath.MakeLower();
CFileFind finder;
DWORD buffSize = MAX_PATH;
char longPath[MAX_PATH];
DWORD result = GetLongPathName(m_szFilePath, longPath, MAX_PATH );

if( result == 0)
{
    m_bExists = FALSE;
    return;
}
m_szFilePath = CString(longPath);
m_szFilePath.Replace("/","\\");
m_szFilePath.Trim();
//check if it does not ends in \ => remove it
int length = m_szFilePath.GetLength();
if( length > 0 && m_szFilePath[length - 1] == '\\' )
{
    m_szFilePath.Truncate( length - 1 );
}
BOOL bWorking = finder.FindFile(this->m_szFilePath);
if(bWorking){
    bWorking = finder.FindNextFile();
    finder.GetCreationTime(this->m_CreationTime);
    m_szFilePath = finder.GetFilePath();
    m_szFileName = finder.GetFileName();

    this->m_szFileExtension = this->GetExtension( m_szFileName );

    m_szFileTitle = finder.GetFileTitle();
    m_szFileURL = finder.GetFileURL();
    finder.GetLastAccessTime(this->m_LastAccesTime);
    finder.GetLastWriteTime(this->m_LastWriteTime);
    m_ulFileSize = static_cast<unsigned long>(finder.GetLength());
    m_szRootDirectory = finder.GetRoot();
    m_bIsArchive = finder.IsArchived();
    m_bIsCompressed = finder.IsCompressed();
    m_bIsDirectory = finder.IsDirectory();
    m_bIsHidden = finder.IsHidden();
    m_bIsNormal = finder.IsNormal();
    m_bIsReadOnly = finder.IsReadOnly();
    m_bIsSystem = finder.IsSystem();
    m_bIsTemporary = finder.IsTemporary();
    m_bExists = TRUE;
    finder.Close();
}else{
    m_bExists = FALSE;
}

Переменная m_szFileName содержит имя файла.

2 голосов
/ 05 августа 2013

Не используйте _splitpath() и _wsplitpath(). Они не безопасны и устарели!

Вместо этого используйте их безопасные версии, а именно _splitpath_s() и _wsplitpath_s()

2 голосов
/ 15 декабря 2011

Это также должно работать:

// strPath = "C:\\Dir\\File.bat" for example
std::string getFileName(const std::string& strPath)
{
    size_t iLastSeparator = 0;
    return strPath.substr((iLastSeparator = strPath.find_last_of("\\")) != std::string::npos ? iLastSeparator + 1 : 0, strPath.size() - strPath.find_last_of("."));
}

Если вы можете использовать его, Qt предоставляет QString (с разбиением, усечением и т. Д.), QFile, QPath, QFileInfo и т. Д. Для манипулирования файлами, именами файлов и каталогами.И, конечно, это также кросс-платформер.

1 голос
/ 20 февраля 2019
std::string getfilename(std::string path)
{
    path = path.substr(path.find_last_of("/\\") + 1);
    size_t dot_i = path.find_last_of('.');
    return path.substr(0, dot_i);
}
0 голосов
/ 28 декабря 2018

shlwapi.lib/dll использует куст реестра HKCU для внутреннего использования.

Лучше не ссылаться на shlwapi.lib, если вы создаете библиотеку или у продукта нет пользовательского интерфейса.Если вы пишете библиотеку, тогда ваш код может быть использован в любом проекте, включая те, которые не имеют пользовательского интерфейса.

Если вы пишете код, который запускается, когда пользователь не вошел в систему (например, служба [или другое] настроена на запуск при загрузке или запуске), тогда HKCU нет.Наконец, шлвапи - это расчетные функции;и в результате высоко в списке, чтобы осудить в более поздних версиях Windows.

0 голосов
/ 23 февраля 2017

Долгое время я искал функцию, способную правильно разложить путь к файлу. Для меня этот код отлично работает как для Linux, так и для Windows.

void decomposePath(const char *filePath, char *fileDir, char *fileName, char *fileExt)
{
    #if defined _WIN32
        const char *lastSeparator = strrchr(filePath, '\\');
    #else
        const char *lastSeparator = strrchr(filePath, '/');
    #endif

    const char *lastDot = strrchr(filePath, '.');
    const char *endOfPath = filePath + strlen(filePath);
    const char *startOfName = lastSeparator ? lastSeparator + 1 : filePath;
    const char *startOfExt = lastDot > startOfName ? lastDot : endOfPath;

    if(fileDir)
        _snprintf(fileDir, MAX_PATH, "%.*s", startOfName - filePath, filePath);

    if(fileName)
        _snprintf(fileName, MAX_PATH, "%.*s", startOfExt - startOfName, startOfName);

    if(fileExt)
        _snprintf(fileExt, MAX_PATH, "%s", startOfExt);
}

Пример результатов:

[]
  fileDir:  ''
  fileName: ''
  fileExt:  ''

[.htaccess]
  fileDir:  ''
  fileName: '.htaccess'
  fileExt:  ''

[a.exe]
  fileDir:  ''
  fileName: 'a'
  fileExt:  '.exe'

[a\b.c]
  fileDir:  'a\'
  fileName: 'b'
  fileExt:  '.c'

[git-archive]
  fileDir:  ''
  fileName: 'git-archive'
  fileExt:  ''

[git-archive.exe]
  fileDir:  ''
  fileName: 'git-archive'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git-core\.htaccess]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: '.htaccess'
  fileExt:  ''

[D:\Git\mingw64\libexec\git-core\a.exe]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: 'a'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git-core\git-archive.exe]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: 'git-archive'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git.core\git-archive.exe]
  fileDir:  'D:\Git\mingw64\libexec\git.core\'
  fileName: 'git-archive'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git-core\git-archiveexe]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: 'git-archiveexe'
  fileExt:  ''

[D:\Git\mingw64\libexec\git.core\git-archiveexe]
  fileDir:  'D:\Git\mingw64\libexec\git.core\'
  fileName: 'git-archiveexe'
  fileExt:  ''

Надеюсь, это поможет и вам:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...