C++ 如何从路径中获取文件名的词干?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5523042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the stem of a filename from a path?
提问by luac
I want to extract a const char* filename from a const char* filepath. I tried with regex but failed:
我想从 const char* 文件路径中提取一个 const char* 文件名。我尝试使用正则表达式但失败了:
const char* currentLoadedFile = "D:\files\file.lua";
char fileName[256];
if (sscanf(currentLoadedFile, "%*[^\]\%[^.].lua", fileName)) {
return (const char*)fileName; // WILL RETURN "D:\files\file!!
}
The issue is that "D:\files\file" will be returned and not the wanted "file"(note: without ".lua")
问题是将返回“D:\files\file”而不是想要的“文件”(注意:没有“.lua”)
回答by marchelbling
What about using std::string? e.g.
使用 std::string 怎么样?例如
std::string path("d:\dir\subdir\file.ext");
std::string filename;
size_t pos = path.find_last_of("\");
if(pos != std::string::npos)
filename.assign(path.begin() + pos + 1, path.end());
else
filename = path;
回答by BatchyX
Just use boost::filesystem
.
只需使用boost::filesystem
.
#include <boost/filesystem.hpp>
std::string filename_noext;
filename_noext = boost::filesystem::path("D:\files\file.lua").stem().string().
const char* result_as_const_char = filename_noext.c_str();
or alternatively, if you want to introduce bugs yourself :
或者,如果您想自己引入错误:
// have fun defining that to the separator of the target OS.
#define PLATFORM_DIRECTORY_SEPARATOR '\'
// the following code is guaranteed to have bugs.
std::string input = "D:\files\file.lua";
std::string::size_type filename_begin = input.find_last_of(PLATFORM_DIRECTORY_SEPERATOR);
if (filename_begin == std::string::npos)
filename_begin = 0;
else
filename_begin++;
std::string::size_type filename_length = input.find_last_of('.');
if (filename_length != std::string::npos)
filename_length = filename_length - filename_begin;
std::string result = input.substr(filename_begin, filename_length);
const char* bugy_result_as_const_char = result.c_str();
回答by tambre
You can do this portably and easily using the new filesystem library in C++17.
您可以使用 C++17 中的新文件系统库轻松轻松地完成此操作。
#include <cstdint>
#include <cstdio>
#include <filesystem>
int main()
{
std::filesystem::path my_path("D:/files/file.lua");
std::printf("filename: %s\n", my_path.filename().u8string().c_str());
std::printf("stem: %s\n", my_path.stem().u8string().c_str());
std::printf("extension: %s\n", my_path.extension().u8string().c_str());
}
Output:
输出:
filename: file.lua
stem: file
extension: .lua
Do note that for the time being you may need to use #include <experimental/fileystem>
along with std::experimental::filesystem
instead until standard libraries are fully conforming.
请注意,在标准库完全符合之前,您可能需要暂时使用#include <experimental/fileystem>
withstd::experimental::filesystem
代替。
For more documentation on std::filesystem
check out the filesystem library reference.
有关std::filesystem
查看文件系统库参考的更多文档。
回答by kushvendra
You can easily extract the file:
您可以轻松提取文件:
int main()
{
char pscL_Dir[]="/home/srfuser/kush/folder/kushvendra.txt";
char pscL_FileName[50];
char pscL_FilePath[100];
char *pscL;
pscL=strrchr(pscL_Dir,'/');
if(pscL==NULL)
printf("\n ERROR :INvalid DIr");
else
{
strncpy(pscL_FilePath,pscL_Dir,(pscL-pscL_Dir));
strcpy(pscL_FileName,pscL+1);
printf("LENTH [%d}\n pscL_FilePath[%s]\n pscL_FileName[%s]",(pscL-pscL_Dir),pscL_FilePath,pscL_FileName);
}
return 0;
}
output:
LENTH [25}
pscL_FilePath[/home/srfuser/kush/folder]
pscL_FileName[kushvendra.txt
回答by int21
// Set short name:
char *Filename;
Filename = strrchr(svFilename, '\');
if ( Filename == NULL )
Filename = svFilename;
if ( Filename[0] == '\')
++Filename;
if ( !lstrlen(Filename) )
{
Filename = svFilename;
}
fprintf( m_FileOutput, ";\n; %s\n;\n", Filename );
回答by lmiguelmh
You could use the _splitpath_s
function to break a path name into its components. I don't know if this is standard C or is Windows specific. Anyway this is the function:
您可以使用该_splitpath_s
函数将路径名分解为其组成部分。我不知道这是标准 C 还是 Windows 特定的。无论如何,这是功能:
#include <stdlib.h>
#include <string>
using std::string;
bool splitPath(string const &path, string &drive, string &directory, string &filename, string &extension) {
// validate path
drive.resize(_MAX_DRIVE);
directory.resize(_MAX_DIR);
filename.resize(_MAX_FNAME);
extension.resize(_MAX_EXT);
errno_t result;
result = _splitpath_s(path.c_str(), &drive[0], drive.size(), &directory[0], directory.size(), &filename[0], filename.size(), &extension[0], extension.size());
//_splitpath(path.c_str(), &drive[0], &directory[0], &filename[0], &extension[0]); //WindowsXp compatibility
_get_errno(&result);
if (result != 0) {
return false;
} else {
//delete the blank spaces at the end
drive = drive.c_str();
directory = directory.c_str();
filename = filename.c_str();
extension = extension.c_str();
return true;
}
}
It is a lot easier and safe to use std::string
but you could modify this to use TCHAR*
(wchar
, char
)...
它使用起来更容易和安全,std::string
但您可以修改它以使用TCHAR*
( wchar
, char
)...
For your specific case:
对于您的具体情况:
int main(int argc, char *argv[]) {
string path = argv[0];
string drive, directory, filename, extension;
splitPath(path, drive, directory, filename, extension);
printf("FILE = %s%s", filename.c_str(), extension.c_str());
return 0;
}
回答by Anders
If you are going to displaya filename to the user on Windows you should respect their shell settings (show/hide extension etc).
如果您要在 Windows 上向用户显示文件名,您应该尊重他们的 shell 设置(显示/隐藏扩展名等)。
You can get a filename in the correct format by calling SHGetFileInfo
with the SHGFI_DISPLAYNAME
flag.
你可以通过调用得到正确格式的文件名SHGetFileInfo
与SHGFI_DISPLAYNAME
标志。
回答by celavek
Hereyou can find an example. I'm not saying it's the best and I'm sure you could improve on that but it uses only standard C++ (anyway at least what's now considered standard). Of course you won't have the features of the boost::filesystem (those functions in the example play along with plain strings and do not guarantee/check you'll actually working with a real filesystem path).
在这里你可以找到一个例子。我并不是说它是最好的,我相信你可以改进它,但它只使用标准的 C++(无论如何至少现在被认为是标准的)。当然,您不会拥有 boost::filesystem 的功能(示例中的那些函数与纯字符串一起播放,并且不保证/检查您实际上会使用真实的文件系统路径)。