0

我正在用 C++ 对几个大文件进行排序。我有一个文本文件,其中包含所有输入文件的名称,每行一个。我想一次读取一个文件名,将它们存储在一个数组中,然后使用每个名称创建一个文件。现在,我正在使用 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++ 中进行谷歌文件处理会更好。如果您是 C 程序员,这开始有点奇怪,但绝对值得努力弄清楚如何以 C++ 方式做事

于 2010-03-02T21:09:51.780 回答
1

您需要添加一个空字节并删除新行,因此在您的第一个 for 循环中编写一个 for 循环,搜索换行符并将其替换为空字节。

尽管其他人是对的,但您在优化尝试中被严重误导。

并确保你释放了你的 malloc。您应该使用 STL 的另一个很好的理由。

于 2010-03-02T21:14:45.177 回答
0

如果您一次读取一行文件,则可以只为每一行分配所需的空间量,并以这种方式构建您的行数组。

我可以理解,这对您来说可能不够快,因此作为替代方案。我可以建议吗

  1. 获取文件的大小
  2. 分配那个大小的缓冲区
  3. 将整个文件读入缓冲区。
  4. 扫描缓冲区,将 \r 和 \n 替换为 \0,并将每行的开头存储在 char* 类型的向量中
于 2010-03-02T21:13:34.940 回答
0

我和其他人在这里,这是过早的优化。

我看不出如何fgets(tempfname[i], 20, fp);编译,更不用说工作了,因为tempfname[i]is astring&并且fgets需要 a char*

可能你想要

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

虽然,在我将在这里进行的许多其他更改中,您可以在每次循环迭代时完全处理一个文件,并完全避免使用名称数组。

于 2010-03-02T21:32:31.147 回答