的路徑提取的文件名和擴展名我都存儲在.log
在這句法的文件列表:我怎樣才能在C++
c:\foto\foto2003\shadow.gif
D:\etc\mom.jpg
我想提取的名稱,並從該文件的擴展名。你能舉一個簡單的方法來做這個例子嗎?
的路徑提取的文件名和擴展名我都存儲在.log
在這句法的文件列表:我怎樣才能在C++
c:\foto\foto2003\shadow.gif
D:\etc\mom.jpg
我想提取的名稱,並從該文件的擴展名。你能舉一個簡單的方法來做這個例子嗎?
要提取的文件名不帶擴展名,使用boost ::文件系統::路徑:: 幹,而不是醜陋的std :: string :: find_last_of(」。「)
boost::filesystem::path p("c:/dir/dir/file.ext");
std::cout << "filename and extension : " << p.filename() << std::endl; // file.ext
std::cout << "filename only : " << p.stem() << std::endl; // file
如果你想要一個安全的方式(即平臺之間的便攜式,而不是假設的道路),我建議使用boost::filesystem
。
它看起來在某種程度上是這樣的:
boost::filesystem::path my_path(filename);
然後你可以從這個路徑提取各種數據。 Here's the documentation of path object.
BTW:還記得,爲了使用路徑喜歡
c:\foto\foto2003\shadow.gif
你一定要逃逸一個字符串的\
:
const char* filename = "c:\\foto\\foto2003\\shadow.gif";
或者使用/
代替:
const char* filename = "c:/foto/foto2003/shadow.gif";
這僅適用於在""
引號中指定文字字符串,從文件加載路徑時,問題不存在。
+1肯定要走的路。主站點上的示例提供了搜索目錄的方法:使用path.extension()方法搜索日誌(請參閱http://www.boost.org/doc/libs/1_36_0/libs/filesystem/doc/index .htm) – Tom 2010-12-13 16:18:43
事實上,在大多數情況下,這是要走的路,但它涉及在某些情況下添加對外部庫的不良依賴。如果你只想使用C++標準提供的東西,我建議你看一下C++的正則表達式,在那裏你可以定義一個正則表達式來做你想做的事情(互聯網上有很多例子)。優點 - 由於一些額外的依賴關係,沒有開銷。然而,這也讓一個問題開放 - 是否需要多平臺?無論您使用的是Windows還是Linux,Boost都會照顧路徑風格。使用正則表達式你必須自己做。 – rbaleksandar 2014-07-11 20:13:00
您必須從std::string
中的文件中讀取您的文件名。您可以使用std::ostream
的字符串提取操作符。一旦你的文件名爲std::string
,你可以使用std::string::find_last_of
方法找到最後一個分隔符。
事情是這樣的:
不想成爲自作聰明,但它應該是path.substr而不是path.substring,對吧? – 2012-02-23 09:10:13
我也使用這個片段以確定適當的斜槓字符:
boost::filesystem::path slash("/");
boost::filesystem::path::string_type preferredSlash = slash.make_preferred().native();
,然後與用於OS優選斜線取代斜線有用的,如果一臺Linux之間不斷部署/ 。窗戶
對於C++ 17:
#include <filesystem>
std::filesystem::path p("c:/dir/dir/file.ext");
std::cout << "filename and extension: " << p.filename() << std::endl; // "file.ext"
std::cout << "filename only: " << p.stem() << std::endl; // "file"
參考文件系統有關:http://en.cppreference.com/w/cpp/filesystem
如所建議的通過@RoiDanto,對於輸出格式,std::out
可以圍繞與報價,例如輸出:
filename and extension: "file.ext"
您可以通過p.filename().string()
轉換std::filesystem::path
到std::string
如果這就是你所需要的,例如:
filename and extension: file.ext
嗨@RoiDanton,感謝編輯!我再次檢查了引用鏈接中的示例代碼,似乎沒有必要將返回類型從'std :: filesystem :: path'轉換爲'std :: string'以便能夠使用'的std :: cout'。 http://en.cppreference.com/w/cpp/filesystem/path/filename但是,如果您認爲不然,請隨時評論或編輯帖子。 – 2017-04-12 14:39:27
這是真的,'std :: cout'可以依靠隱式轉換。然而,由於'std :: cout'後面的註釋表示file.ext和file,無論是'.string()'都必須添加到註釋中,否則它們應該是「file.ext」和「file」。使用Visual C++確實沒有區別(即使沒有'string()'輸出也沒有引號),但對於gcc 6.1,如果忽略'.string()',輸出將帶有引號。見http://coliru.stacked-crooked.com/view?id=a55ea60bbd36a8a3 – 2017-04-12 14:56:44
@RoiDanton,嘿,這是有趣的見解。我會再次更新這篇文章。感謝分享! – 2017-04-12 15:21:02
對於Linux或UNIX機器,操作系統有一個處理的路徑和文件名的兩種功能。使用man 3 basename來獲取有關這些功能的更多信息。 使用系統提供的功能的優點是您不必安裝boost或需要編寫自己的函數。從人頁
#include <libgen.h>
char *dirname(char *path);
char *basename(char *path);
示例代碼:
char *dirc, *basec, *bname, *dname;
char *path = "/etc/passwd";
dirc = strdup(path);
basec = strdup(path);
dname = dirname(dirc);
bname = basename(basec);
printf("dirname=%s, basename=%s\n", dname, bname);
由於非const參數類型的基名()函數,它是一點點非直線前進使用該內部C++代碼。下面是我的代碼庫中的一個簡單示例:
string getFileStem(const string& filePath) const {
char* buff = new char[filePath.size()+1];
strcpy(buff, filePath.c_str());
string tmp = string(basename(buff));
string::size_type i = tmp.rfind('.');
if (i != string::npos) {
tmp = tmp.substr(0,i);
}
delete[] buff;
return tmp;
}
使用new/delete不是很好的樣式。如果兩次調用之間發生任何事情,我可以將它放入try/catch 區塊。
同意。最簡潔地回答問題。 – AndyUK 2014-05-28 12:43:18
實際上,p.filename()是類型路徑,並且在隱式轉換時將被引號包圍,因此您將得到: 文件名和擴展名:「file.ext」 您可能想要p.filename()。 string()代替。 – 2016-02-18 19:54:27
使用C++ 14/C++ 17,你可以使用'std :: experimental :: filesystem'和'std :: filesystem'。見下面的Yuchen Zhong的帖子。 – 2017-04-12 14:15:44