Создание файлов из имен файлов в другом файле C ++ - PullRequest
0 голосов
/ 03 марта 2010

Я работаю над сортировкой нескольких больших файлов в 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

Ответы [ 6 ]

5 голосов
/ 03 марта 2010

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

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

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

2 голосов
/ 03 марта 2010

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

1 голос
/ 03 марта 2010

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

Хотя остальные правы, вы серьезно ошибаетесь в своих попытках оптимизации.

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

1 голос
/ 03 марта 2010

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

0 голосов
/ 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];

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

0 голосов
/ 03 марта 2010

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

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

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