I am attempting to modify some existing C++ code to work with my needs, but having never used C++ before, I am having some difficulties.
My goal is:
--> 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 do not want to just call the C++ program for each file (with, for instance, a shell script) is that prior to the below code running, time and memory-intensive pre-processing steps are performed. (These take about 45-60sec. while the code only takes about 2-5sec. to run.)
I have pasted the section of the code 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;
}
Currently, I am 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. Also, I should add that I’m running these on Windows XP using command prompt.
Thanks.
EDIT:
It now compiles (thanks Blood), though when it runs it is only attempting to open the directory, not the files in the directory.
Problem opening file directory_name.
The ifstream should be opening the files in teh directory, not the directory itself.
EDIT 2:
I am running the executable fromt he command line with the following prompt:
.\tag.exe C:\indir C:\outdir
I have also tried:
.\tag.exe C:\indir\* C:\outdir\
This enumerates all the files, but how can I capture them? Also, is there a simpler way to modify my code/input?
I have also tried:
.\tag.exe C:\indir\ C:\outdir\
This gives: error searching directory.
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)
Solution:
Here are the key changes to the code (thanks 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
The help was very much appreciated.
Make sure you’re passing the right
pathformat toFindFirstFile.From the documentation:
Edit:
I’m not near a windows box right now (so this may not compile!) but I imagine that “loop over each file in a directory” would look something like this: