4

我正在尝试修改一些现有的 C++ 代码以满足我的需要,但是以前从未使用过 C++,我遇到了一些困难。

我的目标是:

--> 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

我不想只为每个文件(例如,使用 shell 脚本)调用 C++ 程序的原因是,在运行以下代码之前,会执行时间和内存密集型的预处理步骤。(这些大约需要 45-60 秒。而代码只需要大约 2-5 秒。运行。)

我已经粘贴了下面的代码部分。我想从命令行读取参数。

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;
}

目前,我收到编译器错误:编辑:编译器错误已修复,感谢 Blood!,但见下文......

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

有什么想法吗?如果您需要更多代码/信息,请告诉我。另外,我应该补充一点,我正在使用命令提示符在 Windows XP 上运行这些。

谢谢。

编辑:

它现在可以编译(感谢 Blood),尽管它在运行时只是尝试打开目录,而不是目录中的文件。

Problem opening file directory_name.

ifstream 应该打开目录中的文件,而不是目录本身。

编辑2:

我正在使用以下提示从命令行运行可执行文件:

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

我也试过:

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

这枚举了所有文件,但我怎样才能捕获它们?另外,有没有更简单的方法来修改我的代码/输入?

我也试过:

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

这给出:错误搜索目录。

编辑 3:

使用:

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

我得到输出:

Problem opening file .

Problem opening file ..

Problem opening file 2967

Problem opening file 2966

Problem opening file 4707

etc. (100s)

解决方案:

以下是代码的主要更改(感谢 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());

并从命令行:

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

非常感谢您的帮助。

4

1 回答 1

4

确保您将正确的path格式传递给FindFirstFile.

文档中

要检查不是根目录的目录,请使用该目录的路径,后面不带反斜杠。例如,“C:\Windows”的参数返回关于目录“C:\Windows”的信息,而不是关于“C:\Windows”中的目录或文件的信息。要检查“C:\Windows”中的文件和目录,请使用“C:\Windows\* ”的 lpFileName。


编辑:

我现在不在 Windows 框附近(所以这可能无法编译!)但我想“循环遍历目录中的每个文件”看起来像这样:

// argv[1] is the input path with no trailing characters, e.g. "c:\indir"

// add a wildcard because FindFirstFile expects e.g. "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, e.g. "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);
于 2012-07-02T20:10:03.457 回答