2013-03-23 161 views
0

我使用下面的代碼讀取一個.dat文件並查找執行時間,它工作得很好。我試圖構建一個循環來讀取多個文件,因爲我有超過20個不同名稱的文件(我需要保留他們的名字),但它不起作用。如何開發此代碼來讀取位於特定文件夾中的所有文件,無論它們有多少? (基於下面的代碼)在C++中讀取多個.dat文件

#include <Windows.h> 
#include <ctime> 
#include <stdint.h> 
#include <iostream> 
using std::cout; 
using std::endl; 
#include <fstream> 
using std::ifstream; 

#include <cstring> 

/* Returns the amount of milliseconds elapsed since the UNIX epoch. Works on both 
* windows and linux. */ 

uint64_t GetTimeMs64() 
{ 


FILETIME ft; 
LARGE_INTEGER li; 

/* Get the amount of 100 nano seconds intervals elapsed since January 1, 1601 (UTC) and copy it 
    * to a LARGE_INTEGER structure. */ 
GetSystemTimeAsFileTime(&ft); 
li.LowPart = ft.dwLowDateTime; 
li.HighPart = ft.dwHighDateTime; 

uint64_t ret; 
ret = li.QuadPart; 
ret -= 116444736000000000LL; /* Convert from file time to UNIX epoch time. */ 
ret /= 10000; /* From 100 nano seconds (10^-7) to 1 millisecond (10^-3) intervals */ 

return ret; 

} 




const int MAX_CHARS_PER_LINE = 512; 
const int MAX_TOKENS_PER_LINE = 20; 
const char* const DELIMITER = "|"; 

int main() 
{ 
    // create a file-reading object 
    ifstream fin; 
    fin.open("promotion.txt"); // open a file 
    if (!fin.good()) 
    return 1; // exit if file not found 

    // read each line of the file 
    while (!fin.eof()) 
    { 
    // read an entire line into memory 
    char buf[MAX_CHARS_PER_LINE]; 
    fin.getline(buf, MAX_CHARS_PER_LINE); 

    // parse the line into blank-delimited tokens 
    int n = 0; // a for-loop index 

    // array to store memory addresses of the tokens in buf 
    const char* token[MAX_TOKENS_PER_LINE] = {}; // initialize to 0 

    // parse the line 
    token[0] = strtok(buf, DELIMITER); // first token 
    if (token[0]) // zero if line is blank 
    { 
     for (n = 1; n < MAX_TOKENS_PER_LINE; n++) 
     { 
    token[n] = strtok(0, DELIMITER); // subsequent tokens 
     if (!token[n]) break; // no more tokens 
    } 
} 

    // process (print) the tokens 
    for (int i = 0; i < n; i++) // n = #of tokens 
     cout << "Token[" << i << "] = " << token[i] << endl; 
    cout << endl; 
    } 
    uint64_t z = GetTimeMs64(); 
    cout << z << endl; 
    system("pause"); 
} 
+0

枚舉目錄中文件的代碼因操作系統而異。你在使用哪種操作系統? – 2013-03-23 04:08:13

+0

@brianbeuning顯然是windows。有''#include '' – gongzhitaao 2013-03-23 04:10:53

回答

1

對於在Windows目錄列表文件,請參閱以下鏈接:

  1. 別:

    有關代碼

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa365200(v=vs.85).aspx

    注意事項t使用fin.eof()來測試輸入的結束,看看爲什麼:eof of istream in C++

  2. 要讀取多個文件,請記住fin.clear()之前fin.close如果您使用相同的fin來讀取多個文件。

UPDATE:

下面的代碼打印出來的文件名稱在目錄D:\\Test。如果您需要子文件夾中每個文件或文件的絕對路徑,請更改GetFiles來完成此操作。根據我提供的鏈接,這非常簡單。代碼是在VS2012 Win7 Pro上測試的。

#include <windows.h> 
#include <Shlwapi.h> 

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 
using namespace std; 

#pragma comment(lib, "Shlwapi.lib") 

int GetFiles(const string &path, vector<string> &files, const string &wildcard = "\\*") 
{ 
    wstring basepath(path.begin(), path.end()); 
    wstring wpath = basepath + wstring(wildcard.begin(), wildcard.end()); 

    WIN32_FIND_DATA ffd; 
    HANDLE hFind = INVALID_HANDLE_VALUE; 
    DWORD dwError = 0; 

    hFind = FindFirstFile(wpath.c_str(), &ffd); 

    if (INVALID_HANDLE_VALUE == hFind) { 
     // display error messages 
     return dwError; 
    } 

    TCHAR buf[MAX_PATH]; 
    do { 
     if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 
      // directory 
     } else { 
      PathCombine(buf, basepath.c_str(), ffd.cFileName); 
      wstring tmp(buf); 
      files.push_back(string(tmp.begin(), tmp.end())); 
     } 
    } while (FindNextFile(hFind, &ffd)); 

    dwError = GetLastError(); 
    if (ERROR_NO_MORE_FILES != dwError) { 
     // some errors 
    } 
    FindClose(hFind); 
    return dwError; 
} 

int main() 
{ 
    string path("D:\\Documents\\Visual Studio 2012\\Projects\\SigSpatial2013"); 
    vector<string> files; 
    GetFiles(path, files); 
    string line; 
    ifstream fin; 
    for (int i = 0; i < files.size(); ++i) { 
     cout << files[i] << endl; 

     fin.open(files[i].c_str()); 
     if (!fin.is_open()) { 
      // error occurs!! 
      // break or exit according to your needs 
     } 

     while (getline(fin, line)) { 
      // now process every line 
     } 

     fin.clear(); 
     fin.close(); 
    } 
} 
+0

1.我從鏈接中瞭解到while(!fin.eof())是讀取文件的錯誤方式,但是我可以使用什麼呢?我找不到2.我應該在閱讀目錄之前列出目錄中的文件,因爲我試圖閱讀這些文件的內容 – Hawk 2013-03-24 05:25:07

+0

@HaythamAlzeini 1.您如何獲取文件名?如果你將硬編碼,那麼你不必。我提供的是一種在目錄中獲取文件名的方法。 2.對於''fin'',你可以使用下面的代碼框架:''int a; while(fin >> a){// do something}''。 – gongzhitaao 2013-03-24 14:42:51

+0

當我執行列表代碼時,顯示如下:'Usage:Users \ Alzeini \ Desktop \ New folder \ untitled3.exe '是項目文件的路徑,是否正確?放置我的代碼?利用這個輸出。 – Hawk 2013-03-27 02:08:03

1

我覺得它更容易:

1,如果你分析出,讀取文件中的代碼並處理有關內容納入其自身的功能:
void process_file(char* filename);
2 - 添加新的功能,列出目錄的內容:char** list_dir(char* dir);
3-結合2個功能在你的main()

這使得對更清潔,更可測試的代碼

1

我同意封裝這個建議。 在Windows上,代碼如下所示

HANDLE h; 
WIN32_FIND_DATA find_data; 
h = FindFirstFile("*.dat", & find_data); 
if(h == INVALID_HANDLE_VALUE) { 
    // Error 
    return; 
} 
do { 
    char * s = find_data.cFileName; 
      // Your code here 
} while(FindNextFile(h, & find_data)); 
FindClose(h); 
+0

我用你的建議重寫了代碼,但沒有奏效,我認爲我的代碼有問題,我剛剛在char * s後插入了讀取文件的代碼(沒有時間戳部分)到你的代碼中= ...;你能告訴我什麼可能是錯的嗎? – Hawk 2013-03-26 16:01:54

+0

@HaythamAlzeini沒有看到新的代碼。 – 2013-03-27 00:37:55

+0

這裏是我問的一段代碼,如何將我的代碼與你的代碼合併? 'do {char _s = find_data.cFileName; //我的代碼 ifstream fin; fin.open(「promotion.txt」); //打開文件 if(!fin.good()) return 1; (如果找不到文件,請退出) //讀取文件的每一行 while(!fin.eof()) {... //其餘代碼.. } while FindNextFile(h,&find_data )); FindClose(h);' – Hawk 2013-03-30 07:21:57