Создавать файлы из имен файлов в другом файле С++

Я работаю над сортировкой нескольких больших файлов на С++. У меня есть текстовый файл, содержащий имена всех входных файлов, по одному в каждой строке. Я хотел бы прочитать имена файлов по одному, сохранить их в массиве, а затем создать файл с каждым из этих имен. Прямо сейчас я использую 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()?

Большое спасибо, бсг


person bsg    schedule 02.03.2010    source источник


Ответы (6)


Как сказал Дон Кнут, преждевременная оптимизация — корень всех зол.

Ваши имена файлов определенно не являются узким местом! Просто используйте для них std::string.

Однако вам нужно заменить fp = fopen(tempfname[i], "w"); на fp = fopen(tempfname[i].c_str(), "w");.

person Vlad    schedule 02.03.2010

Забудьте об оптимизации на этом этапе.
Используйте std::vector<std::string>, и ваша программа заработает. Как только он заработает, если скорость действительно так важна, вы можете вернуться и изменить его.

person hamishmcn    schedule 02.03.2010

вы используете идиомы типа C, было бы лучше, если бы вы использовали обработку файлов Google на C++. что немного странно для начала, если вы программист C, но определенно стоит усилий, чтобы понять, как сделать что-то на C++

person Keith Nicholas    schedule 02.03.2010

Вам нужно добавить нулевой байт и удалить новую строку, поэтому напишите цикл for в своем первом цикле for, который ищет новую строку и заменяет ее нулевым байтом.

Хотя другие правы, что вы серьезно заблуждаетесь в своих попытках оптимизации.

И убедитесь, что вы освобождаете то, что вы malloc. Еще одна веская причина, по которой вам следует использовать STL.

person Bill Prin    schedule 02.03.2010

Если вы читаете файлы по одной строке за раз, вы можете выделить только тот объем пространства для каждой строки, который необходим, и построить свой массив строк таким образом.

Я понимаю, что это может быть недостаточно быстро для вас, так что в качестве альтернативы. могу я предложить

  1. получить размер файла
  2. выделить буфер такого размера
  3. прочитать весь файл в буфер.
  4. сканировать буфер, заменяя \r и \n на \0 и сохраняя начало каждой строки в векторе типа char*
person John Knoeller    schedule 02.03.2010

Я со всеми здесь, это преждевременная оптимизация.

Я не понимаю, как fgets(tempfname[i], 20, fp); может компилироваться, а тем более работать, поскольку tempfname[i] — это string&, а fgets требует char*.

Вероятно, вы хотите

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

Хотя, среди многих других изменений, которые я бы сделал здесь, вы могли бы полностью обрабатывать файл на каждой итерации цикла и полностью избежать массива имен.

person Potatoswatter    schedule 02.03.2010