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

ファイルごとに(たとえば、シェルスクリプトを使用して)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&>

何かご意見は?さらにコード/情報が必要な場合はお知らせください。また、コマンドプロンプトを使用してWindowsXPでこれらを実行していることを追加する必要があります。

ありがとう。

編集:

これでコンパイルされます(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 に答える