2013-03-23 4 views
0

Я использовал код ниже, чтобы прочитать один .dat-файл и найти время выполнения, он работал очень хорошо. Я попытался создать цикл для чтения нескольких файлов, так как у меня более 20 файлов с разными именами (мне нужно сохранить их имена), но это не сработало. Как я могу разработать этот код для чтения всех файлов, расположенных в определенной папке, независимо от того, сколько они? (На основании следующего кода)Прочтите несколько файлов .dat в C++

#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

Код для перечисления файлов в каталоге варьируется в зависимости от операционной системы. Какую ОС вы используете? –

+0

@brianbeuning Видимо, окна. Существует '' #include '' – gongzhitaao

ответ

1

Для получения списка файлов в каталоге на Windows, обратитесь к этой ссылке:

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

Заметки о коде:

  1. Дон» 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

+0

@HaythamAlzeini 1. Как вы получите имена файлов? Если вы будете жестко закодировать, то вам это не нужно. То, что я предоставил, - это способ получить имя файла в каталоге. 2. для '' fin'', вы можете использовать следующий скелет кода: '' int a; while (fin >> a) {// делаем что-то} ''. – gongzhitaao

+0

Когда я выполняю код листинга, он отображает это: «Использование: Пользователи \ Alzeini \ Desktop \ Новая папка \ untitled3.exe <имя_каталога>>, это путь к файлу проекта, это правильно ?, если так, где я должен разместить мой код? использовать этот выход. – Hawk

1

Я думаю, что легче:

1- если вы вынесете код, который считывает файл и обработать его содержимое в отдельную функцию:
void process_file(char* filename);
2- добавить новую функцию перечислить содержание справочника: char** list_dir(char* dir);
3- объединить 2 функции в основных()

это делает для более чистой и проверяемой коды

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

+0

@ HaythamAlzeini Не видите новый код. –

+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

Смежные вопросы