0

C++ でいくつかの大きなファイルの並べ替えに取り組んでいます。各行に 1 つずつ、すべての入力ファイルの名前を含むテキスト ファイルがあります。ファイル名を一度に 1 つずつ読み取り、それらを配列に格納してから、それらの名前ごとにファイルを作成したいと思います。現在、文字配列を必要とする fopen と fread を使用しているため (速度を最適化しようとしています)、ファイル名は文字配列の配列に読み込まれます。ただし、これらの配列には事前に最大サイズを固定する必要があるため、ファイル名が最大サイズよりも小さい場合、残りはゴミでいっぱいになります。次に、その配列を fopen() でファイル名として使用しようとすると、文字列の末尾にゴミがあるため、ファイルが認識されません。どうすればこの問題を解決できますか? これが私のコードです:

 #include <iostream>
#include <fstream>
#include <string>
#include "stdafx.h"
#define NUM_INPUT_FILES 4

using namespace std;



FILE *fp;
unsigned char *buff;
FILE *inputFiles[NUM_INPUT_FILES];


int _tmain(int argc, _TCHAR* argv[])
{


    buff = (unsigned char *) malloc(2048);
    char j[8];
    char outputstring[] = "Feelings are not supposed to be logical. Dangerous is the man who has rationalized his emotions. (David Borenstein)";

    fp = fopen("hello.txt", "r");

    string tempfname[NUM_INPUT_FILES];
    //fp = fopen("hello.txt", "r");
    for(int i=0;i<NUM_INPUT_FILES;i++)
    {
        fgets(tempfname[i], 20, fp);
        cout << tempfname[i];
    }
    fclose(fp);

    for(int i=0; i<NUM_INPUT_FILES;i++)
    {
        fp = fopen(tempfname[i], "w");
        //fwrite(outputstring, sizeof(char), sizeof outputstring/sizeof(char), fp);
        if(fp)
        {
            fclose(fp);}
        else
            cout << "sorry" << endl;
    }


    return 0;
}

また、fwrite() で書き出すバッファのサイズを調べるにはどうすればよいですか?

どうもありがとう、bsg

4

6 に答える 6

5

Don Knuth が言ったように、時期尚早の最適化は諸悪の根源です。

ファイル名は間違いなくボトルネックではありません! それらに使用std::stringするだけです。

fp = fopen(tempfname[i], "w");ただし、に置き換える必要がありますfp = fopen(tempfname[i].c_str(), "w");

于 2010-03-02T21:09:36.887 に答える
2

この段階での最適化は忘れてください。プログラム
を使用して動作させます。std::vector<std::string>機能したら、速度が本当に重要な場合は、戻って変更できます

于 2010-03-02T21:10:34.953 に答える
1

C タイプのイディオムを使用している場合は、C++ で Google ファイル処理を行う方がよいでしょう。あなたがCプログラマーである場合、これを始めるのは少し奇妙ですが、C++の方法で物事を行う方法を考え出す努力は間違いなく価値があります

于 2010-03-02T21:09:51.780 に答える
1

null バイトを追加して新しい行を削除する必要があるため、最初の for ループ内に、改行を検索して null バイトに置き換える for ループを記述します。

他の人は正しいですが、最適化の試みで深刻な誤解を招いています.

そして、mallocしたものを解放していることを確認してください。STL を使用すべきもう 1 つの正当な理由があります。

于 2010-03-02T21:14:45.177 に答える
0

私はここにいる他のみんなと一緒です。これは時期尚早の最適化です。

は であり、が必要であるfgets(tempfname[i], 20, fp);ため、どのようにコンパイルできるかわかりません。tempfname[i]string&fgetschar*

おそらくあなたが欲しい

typedef char file_name[20]; // way too short
file_name tempfnames[NUM_INPUT_FILES];

ここで行う多くの変更の中でも特に、各ループ反復でファイルを完全に処理し、名前の配列を完全に回避することができます。

于 2010-03-02T21:32:31.147 に答える
0

一度に 1 行ずつファイルを読み取る場合は、各行に必要なスペースだけを割り当てて、そのように行の配列を構築できます。

これはあなたにとって十分な速さではないかもしれないことは理解できますので、代替手段として。提案してもいいですか

  1. ファイルのサイズを取得する
  2. そのサイズのバッファを割り当てます
  3. ファイル全体をバッファに読み込みます。
  4. バッファをスキャンして \r と \n を \0 に置き換え、各行の開始を char* 型のベクトルに格納します
于 2010-03-02T21:13:34.940 に答える