我正在撰寫一個程式來在 Linux 中復制檔案。該程式有兩個引數:
- a
char *source這是需要復制的源檔案的路徑 - a這是到將制作
char *dest副本的目的地的路徑source
我正在使用fopen(3)函式打開檔案。
到目前為止,我注意到 fopen() 無法識別常見的 bash shell 擴展,例如:
~當前用戶的主目錄
為了處理這個問題,我可以使用 switch/if 陳述句并檢查源路徑 ( char *source) 是否有任何字符并采取相應的行動。這個解決方案意味著我必須構建一個絕對路徑(來自/又名根目錄示例的路徑:) /usr/dir2/books/maths.pdf/。理想情況下,我想要一個可以在用戶所在的任何當前作業目錄的任何路徑上作業的解決方案。
我的問題是:有沒有更好的方法來處理這個問題?我如何以可移植和有效的方式處理路徑?
uj5u.com熱心網友回復:
到目前為止,我注意到
fopen()無法識別常見的 bash shell 擴展
確實沒有。 shell擴展(如波浪號替換和通配符)由 shell執行。如果您也希望它們由您的程式執行,那么您需要自己實作。另一方面,您不必擔心參考對 shell 很重要的字符,因為除非您實作它,否則您不會得到分詞等。
有沒有更好的方法來處理這個?我如何以可移植和有效的方式處理路徑?
處理它的一個很好的方法是讓其他人處理它。特別是,如果有問題的檔案名被指定為命令列引數,那么擴展將由 shell 處理(或不處理),在用戶的控制下。在這種情況下,用戶不會期望您的程式執行額外的擴展。如果檔案名來自另一個源(組態檔、檔案選擇器),那么期望給出完整路徑或可能給出正確的相對路徑是合理的。
如果您仍然想特別處理裸波浪線的 bash 式擴展,那么這并不難。它僅適用于作為檔案名的第一個字符出現的波浪號,并將其擴展為 environment variable 的值HOME。您可以使用 讀取環境變數getenv(),除此之外,您只需要一些相對簡單的字串操作。
更一般的波浪號擴展,~username出現在檔案名開頭的位置被擴展到 user 的主目錄username,需要您查閱用戶(又名密碼)資料庫。在 POSIX 系統上,一種自然的方法是通過getpwnam()函式。
請注意,不同的 shell 在它們執行的擴展和執行它們的條件方面表現出差異。您不能同時模擬所有 shell,因此將擴展留給外部關注是最便攜和最有效的選擇。
uj5u.com熱心網友回復:
考慮使用 POSIXwordexp()函式(或者可能是 POSIX
glob())基于 bash 擴展將輸入字串轉換為檔案串列。
看:
- man wordexp — https://man7.org/linux/man-pages/man3/wordexp.3.html
- 人 glob — https://man7.org/linux/man-pages/man3/glob.3.html
效率不是很高,因為它派生了一個 shell 來執行擴展,但它完成了這項作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/497977.html
上一篇:洗掉文本檔案中后跟空格的換行符
