C ++ Looping through files in a directory and writing to another directory

I am trying to change some existing C ++ code to work with my needs, but have never used C ++ before, I am having some difficulties.

My goal:

--> time and memory-intensive processes for preparation for each file in directory: open file; generate a tagged representation; //the current code just does this write file; //different directory but same filename 

The reason I don’t just want to call a C ++ program for each file (for example, with a shell script) is because before the execution of the code below, the steps of preprocessing time and memory are performed (This will take about 45-60 seconds, and it takes only 2-5 seconds to execute the code).

I inserted the code section below. I want to read the arguments from the command line.

 int main(int argc, char** argv) { /* pre-processing stuff */ /* for each file */ HANDLE hFind = INVALID_HANDLE_VALUE; string path = argv[1]; string outpath = argv[2]; WIN32_FIND_DATA ffd; //EDIT 2: cout << "Path: " << path << '\n'; cout << "Outpath: " << outpath << '\n'; hFind = FindFirstFile(path.c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { cout << "error searching directory\n"; return false; } do { //istream *is(&std::cin); string filePath = path + ffd.cFileName; ifstream in( filePath.c_str() ); if (in) { /* for each line */ string line; int n = 1; string str; string fullOutpath = outpath + ffd.cFileName; ofstream File; File.open(fullOutpath); while (getline(in, line)) { if (line.size() > 1024) { cerr << "warning: the sentence seems to be too long at line " << n; cerr << " (please note that the input should be one-sentence-per-line)." << endl; } string postagged = bidir_postag(line, vme, vme_chunking, dont_tokenize); /* output to file */ File << postagged << endl; //cout << postagged << endl; /* increment counter */ n++; } File.close(); } else { cout << "Problem opening file " << ffd.cFileName << "\n"; } } while (FindNextFile(hFind, &ffd) != 0); if (GetLastError() != ERROR_NO_MORE_FILES) { cout << "Something went wrong during searching\n"; } return true; } 

I am currently getting a compiler error: EDIT : compiler error fixed, thanks Blood !, but see below ...

 error: no matching function for call to 'std::basic_ofstream<char>::open<std::string&> 

Any thoughts? Please let me know if you need more code / information. In addition, I must add that I run them in Windows XP using the command line.

Thanks.

EDIT:

Now it compiles (thanks to Blood), but when it starts, it only tries to open the directory, not the files in the directory.

 Problem opening file directory_name. 

Ifstream should open files in the directory, not in the directory itself.

EDIT 2:

I run the executable from the command line with the following prompt:

 .\tag.exe C:\indir C:\outdir 

I also tried:

 .\tag.exe C:\indir\* C:\outdir\ 

This lists all the files, but how can I capture them? Also, is there an easier way to change my code / input?

I also tried:

 .\tag.exe C:\indir\ C:\outdir\ 

This gives: a directory for finding errors.

EDIT 3:

Using:

 .\tag.exe "C:\indir\*" C:\outdir\ 

I get the output:

 Problem opening file . Problem opening file .. Problem opening file 2967 Problem opening file 2966 Problem opening file 4707 etc. (100s) 

Decision:

Here are the key changes to the code (thanks to Nate Kohl!):

 string path = argv[1]; path += "\\*"; hFind = FindFirstFile(path.c_str(),&ffd); // in the 'do-while' loop string filePath = argv[1]; filePath += "\\"; filePath += ffd.cFileName; ifstream in(filePath.c_str()); //regarding the outpath fullOutpath = outpath + "\\"; fullOutpath += ffd.cFileName; File.open(fullOutpath.c_str()); 

and from the command line:

 .\tag.exe C:\indir C:\outdir 

Help was greatly appreciated.

+4
source share
1 answer

Make sure you pass the correct path format to FindFirstFile .

From the documentation :

To check a directory that is not a root directory, use the path to that directory without a backslash. For example, the argument "C: \ Windows" returns information about the directory "C: \ Windows" and not about the directory or file in "C: \ Windows". To view files and directories in "C: \ Windows", use lpFileName for "C: \ Windows \ * ".


Edit:

I'm not near the window right now (so this may not compile!), But I think that the “loop over each file in the directory” would look something like this:

 // argv[1] is the input path with no trailing characters, eg "c:\indir" // add a wildcard because FindFirstFile expects eg "c:\indir\*" TCHAR wildcard_path[MAX_PATH]; PathCombine(wildcard_path, argv[1], "*"); // iterate over each file WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFile(wildcard_path, &ffd); if (hFind == INVALID_HANDLE_VALUE) { } // error do { // ignore directories if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // create a full path for each file we find, eg "c:\indir\foo.txt" TCHAR file_path[MAX_PATH]; PathCombine(file_path, argv[1], ffd.cFileName); // ...and do something with file_path. } } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); 
+4
source

All Articles