2014-12-23 48 views
1

我想在C中做一個功能來刪除臨時文件夾的所有內容並刪除文件夾。
雖然我已經成功創建了循環遍歷文件和刪除文件夾的代碼(這非常簡單),但我無法使用unlink刪除文件。
這裏是我使用的代碼:C - 取消鏈接/刪除會產生空格的文件名錯誤

int delete_folder(char *foldername) { 
DIR *dp; 
struct dirent *ep; 
dp=opendir(foldername); 
if (dp!=NULL) { 
     readdir(dp); readdir(dp); 
     while (ep=readdir(dp)) { 
      char* cell = concatenate(concatenate(foldername, "\\"), "Bayesian Estimation.xlsx");//ep->d_name); 
      printf("%s\n", cell); 
      remove(cell); 
      printf("%s\n", strerror(errno)); 

     } 
     closedir(dp); 
} 
if (!rmdir(foldername)) {return(0);} else {return(-1);} 
} 

,我寫的是全功能的所有文件,但是那些文件名中包含空格的代碼。經過一些測試後,我可以保證取消鏈接功能可以消除文件夾中的所有文件(即使文件名中包含特殊字符的文件),但如果文件名包含空格,將會失敗(但是,對於同一個文件,如果刪除空間),此功能再次工作)。

有其他人遇到過這個問題嗎?而且,更重要的是,它可以解決/散佈嗎?
(即使我直接引入空間轉義序列,問題仍然存在)
unlink提供的錯誤是「沒有這樣的文件或目錄」(ENOENT)。請注意,該文件確實位於引用的位置(可通過在變量單元格中輸出正確文件名的代碼進行驗證),並且如果使用刪除功能而不是取消鏈接,也會發生此錯誤。

PS:函數連接是我自己製作的函數,它輸出兩個輸入字符串的連接。

編輯: 該代碼是在Windows代碼塊中編寫的。
這裏的連擊功能代碼:

char* concatenate(char *str1, char *str2) { 
int a1 = strlen(str1), a2 = strlen(str2); char* str3[a1+a2+1]; 
snprintf(str3, a1+a2+2, "%s%s", str1, str2); 
return(str3); 
} 

雖然你說,這是可能的(容易)內存泄漏是正確的,功能輸入和輸出是生成的代碼,並僅供個人使用,因此沒有太大的理由擔心它(沒有真正需要防止代碼被愚弄)。

+0

'concatenate'是否使用'malloc()'來分配連接字符串?他們如何獲得免費()ed? – Barmar

+0

@Barmar,這顯然是一個測試用例,正如_actual_ rest-of-line在評論之後的事實所證明的那樣。在任何情況下,_show_ us'concatenate()',_we_無法確定它是否像廣告一樣工作。 – paxdiablo

+0

我想不出有什麼理由解決這個問題。 'unlink'和'remove'不會解析文件名,除非找到'/'目錄分隔符。 – Barmar

回答

0

非常感謝您的所有輸入,在審查了您的意見,並做了一些實驗後,我發現remove/unlink不起作用因爲文件名只是暫時保存在變量單元格(這是足夠長的時間才能正確打印到控制檯,因此我的困惑)在適當地存儲我的文件名在使用之前,我的問題已經完全解決了
下面的代碼(我已經與文件名選中它作爲複雜的,因爲我可以讓他們):

int delete_folder(char* foldername) { 
DIR *dp; 
struct dirent *ep; 
dp=opendir(foldername); 
if (dp!=NULL) { 
     readdir(dp); readdir(dp); 
     while (ep=readdir(dp)) { 
      char cell[strlen(foldername)+1+strlen(ep->d_name)+1]; 
      strcpy(cell, concatenate(concatenate(foldername, "\\"), ep->d_name)); 
      unlink(cell); 
      printf("File \"%s\": %s\n", ep->d_name, strerror(errno)); 
     } 
     closedir(dp); 
} 
if (!rmdir(foldername)) {return(0);} else {return(-1);} 
} 

我意識到這是怎樣的一個小白錯誤的,從我是一個有點生疏的產生而在C編程,所以...非常感謝您的全力幫助!

1

你說「使用unlink()」,但代碼是使用remove()。你在哪個平臺上?通過運行一個不能正確處理文件名中空格的外部命令,您的平臺是否存在任何危險:您的平臺執行remove()?在大多數系統中,這不會是一個問題。

什麼問題是,在打印錯誤之前,您不檢查remove()的返回值。如果函數指出它產生了一個錯誤,你應該只打印錯誤。標準C(或POSIX)庫中沒有功能將errno設置爲零。此外,錯誤應報告在標準錯誤;這就是標準錯誤流的用途。

if (remove(cell) != 0) 
    fprintf(stderr, "Failed to remove %s (%d: %s)\n", cell, errno, strerror(errno)); 
else 
    printf("%s removed OK\n", cell); 

我認爲else子句是一個臨時的措施,當你得到的代碼工作。

它也看起來像你像一個諺語篩漏記憶。您在cell中捕獲雙連接操作的結果,但是您永遠不會釋放它。事實上,如果嵌套調用都分配內存,那麼即使在循環結尾添加free(cell);(在循環內部,在第二個printf(),我解構後),也會發生泄漏。如果concatenate()每次都沒有分配新內存(它返回一個指向靜態分配的內存的指針,那麼我認爲將字符串與concatenate()的輸出連接在一起也是危險的,可能會在您將字符串複製到自身時調用未定義的行爲。看看concatenate()的代碼,並/或提交它的分析

相關問題