2012-03-03 50 views
0

我正在嘗試訪問目錄中的所有文件,並在此文件和後續目錄下的文件上執行一些操作。對於這個操作,我使用了windows的dirent.h,它設法獲取所有文件並打開和關閉這些文件。我的問題是,當我嘗試從他們那裏讀取某些內容並寫入另一個內容時,如下所示,我得到了最後顯示的錯誤。下面的遞歸目錄搜索和文件打開有什麼問題?

下面是代碼:

#include <iostream> 
#include <cstring> 
#include <sys/stat.h> 
#include <dirent.h> 
FILE *test_file; 
char buffer[51]; 
void listdir(const char *path) 
{ 
    struct dirent *entry; 
    DIR *dp; 

    //std::cout << "Dir: " << path << "\n"; 

    if(dp = opendir(path)) 
    { 
    struct stat buf ; 
    FILE *input_file; 

    while((entry = readdir(dp))) 
    { 
     std::string p(path); 
     p += "\\"; 
     p += entry->d_name; 
     char fpath[250]; 
     //strcpy(fpath,path); 
     if(!stat(p.c_str(), &buf)) 
     { 
      if(S_ISREG(buf.st_mode)) 
      { 
       std::cout << " File: " << entry->d_name << "\n"; 
       sprintf(fpath,"%s\\%s",path,entry->d_name); 
       input_file=fopen(fpath,"r+b"); 
       test_file=fopen("test_test.txt","a+b"); 
       if(input_file==NULL) 
       { 
       std::cout<<"\n Could not open\n"<<entry->d_name<<std::endl; 
       continue; 
       } 
       if(test_file==NULL) 
        goto z; 
       else 
       { 
        std::cout<<"\n Successfully Opened\n"<<fpath; 
        fread(buffer,50,1,input_file); 
        fprintf(test_file,"\n\n%s\n\n",fpath); 
        fwrite(buffer,50,1,test_file); 

        fclose(input_file); 
        fclose(test_file); 
        // free(buffer); 
       } 
z: 
       if(test_file=NULL) 
       fclose(test_file); 
      } 
      if(S_ISDIR(buf.st_mode) && 
     // the following is to ensure we do not dive into directories "." and ".." 
         strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) 
      { 
       listdir(p.c_str()); 
      } 
     } 
     else 
      std::cout << "ERROR in stat\n"; 
    } 
    // delete buf; 
    closedir(dp); 
    } 
    else 
    std::cout << "ERROR in opendir\n"; 
    fclose(test_file); 
} 

int main(int argc, char **argv) 
{ 
    listdir(argv[1]); 
    return 0; 
} 

它設法打開和讀取的第一個文件,但第一個文件後,它會顯示以下錯誤和開放dbgheap.c

HEAP [direntdir.exe]:指定給RtlValidateHeap的無效地址( 002C0000,002C5718)Windows在 direntdir.exe中觸發了一個斷點。

這可能是由於堆損壞引起的,這表示 direntdir.exe或其中已加載的任何DLL的錯誤。

這可能也是由於用戶按下F12而direntdir.exe具有 的重點。

輸出窗口可能有更多診斷信息。

編輯: 糾正錯誤與BUF變量。

現在我得到

調試斷言失敗!

...表達式:(!緩衝= NULL)...

+0

你既釋放和刪除'buf'(其本身是高度可疑的)和AFAICT,從不爲任何地方分配存儲空間(甚至不初始化它)。 (C風格的代碼和C++的混合是相當混亂的。) – Mat 2012-03-03 16:59:17

回答

2

你有兩個變量命名buf

char* buf; 
... 
struct stat *buf = new struct stat; 

後者隱藏第一,後者是free() d,連儘管它是使用new創建的,然後在不重新分配的情況下重用。 後者也用作fread()的參數。重命名char* buf並可能使其局部的功能和只使用一個堆棧分配的緩衝區:

char fread_buffer[51]; 

編輯:

char* buffer從來沒有分配給它,它在fread()使用之前存儲器中,以便在調用fread()可能是寫在記憶中的任何地方更改爲:

char buffer[50]; /* as only 50 bytes are read from the file */ 

,如果它是這樣聲明的buffer不叫free()

此外,爲了簡化事情就宣佈buf爲:

struct stat buf; 

,並呼籲stat()

if(!stat(p.c_str(), &buf)) 

使這兩個變化將代碼中刪除所有動態內存管理。

編輯2:

if是賦值,而不是一個不等式檢查:

if(test_file=NULL) 
    fclose(test_file); 

應該是:

if(NULL != test_file) 
    fclose(test_file); 
+0

我剛剛看到並糾正它,但仍然是相同的問題 – John 2012-03-03 17:04:25

+0

您是否更改'緩衝區'的聲明? – hmjd 2012-03-03 17:21:22

+0

我根據您的建議更正了我的代碼。但是現在我得到** Debug Assertion Faild。 ....表達式(流== NULL)** – John 2012-03-03 17:21:38