Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Конкатинация 2 текстовых файлов


Автор: RDC 2.6.2008, 01:59
Как наиболее оптимально соединить несколько текстовых файлов в один?

Автор: mrbrooks 2.6.2008, 07:43
Я бы их соединил используя TStringList.

Автор: rrrFer 2.6.2008, 07:53
RDC, 
Цитата

наиболее оптимально

я думаю просто дописать один файл в конец другого

Автор: mrbrooks 2.6.2008, 07:57
Поясню. Допустим у тебя есть файл 1.txt и 2.txt. Тебе их надо сложить скажем в 3.txt

Код

TStringList *list1 = new TStringList();
TStringList *list2 = new TStringList();
list1->LoadFromFile("1.txt");
list2->LoadFromFile("2.txt");
list1->AddStrings(list2);
list1->SaveToFile("3.txt");
delete list1;
delete list2;


Вот такой шаблон. Конечно есть смысл ввести проверку на наличие файлов или отловить исключение. Так же можешь отсортировать содержимое файлов в алфавитном порядке и т.д. Дерзай имхо  smile 

Автор: Lazin 2.6.2008, 08:11
Цитата(mrbrooks @  2.6.2008,  07:43 Найти цитируемый пост)
Я бы их соединил используя TStringList. 

этом случае придется загрузить оба файла в память, а если они большие? 
намного проще создать новый файл - 3.тхт, открыть его для записи, файл 1.тхт открыть для чтения, читать его построчно(или блоками) и записывать то что прочитали в 3.тхт, потом открыть 2.тхт и сделать с ним то-же что и с 1.тхт
после каждой записи, файловый указатель будет смещаться в конец файла, так что новая порция данных будет дописываться в конец файла


Автор: mrbrooks 2.6.2008, 08:18
Цитата(Lazin @ 2.6.2008,  08:11)
этом случае придется загрузить оба файла в память, а если они большие? 

Об этом автор умалчивает. Если большие то конечно данный метод не совсем резонен. Тогда смысл вообще создавать 3 - й файл, можно открыть первый на запись а со второго добовлять в него. На самом деле если речь идет о дохленькой тачке то вопросов нет. Но раз чек обратился к Борману то есть смысл использовать VCL  smile  иначе тогда в общие вопросы.

Автор: rrrFer 2.6.2008, 08:30
rrrFer, 
Код

#include <iostream>
using namespace std;
void main(){
    system("cd /d C:  && copy 1.txt+2.txt 3.txt ");
}

Автор: mrbrooks 2.6.2008, 08:32
Цитата(rrrFer @ 2.6.2008,  08:30)
rrrFer, 
Код

#include <iostream>
using namespace std;
void main(){
    system("cd /d C:  && copy 1.txt+2.txt 3.txt ");
}

эротично. хм. если речь конечно идет о консоле.

Автор: RDC 2.6.2008, 09:07
Спасибо всем за ответы. Оба варианта я пробовал. Первый плох тем что медленный, а второй плох тем что в случае ошибок, например отсутствия файлов или ещё что нибудь, плохо отлавливать ошибки. Может ещё что нибудь предложите? 

Автор: chaos 2.6.2008, 09:10
на мой взгляд самый правельный вариант: используй файлы отображаемые в память!!!

Добавлено @ 09:11
пример превести не могу - сижу под линухом.
но думаю сложностей не будет

ЗЫ если чо спрашивай по поводу файлов отображаемых в память

Добавлено @ 09:14
можно smile если есть жлание использовать cmd'шные команды smile
например 
Код

cat f1>f && cat f2>>f


ЗЫ ой, не заметил что консоль уже предлагали smile

Автор: rrrFer 2.6.2008, 09:26
RDC, 
Код

#include <iostream>
using namespace std;
void alarm(char name[]){
    cout<<"cannot open file "<<name<<endl;
    system("pause");abort();
}
void main(){
    FILE *in=fopen("C:\\1.txt","r");
    if(!in)
        alarm("1.txt");
    fclose(in); in=fopen("C:\\2.txt","r");
    if(!in)
        alarm("2.txt");
    system("cd /d C:  && copy 1.txt+2.txt 3.txt ");
    fcloseall();
}

а чем тебя не устраивает дописать один файл к другому? Можно ведь по строчкам переписать сразу...наверно достаточно бысто будет.
или так:
Код

#include <iostream>
#include <fstream>
using namespace std;
void alarm(char name[]){
    cout<<"cannot open file "<<name<<endl;
    system("pause");
    fcloseall();
}
int main(){
    system("cd /d C: && erase err.txt /q");
    system("dir C:\ /b | find \"1.txt\" >> C:\err.txt");
    ifstream f("C:\\err.txt");f.get();
    if(f.eof()){
        alarm("1.txt");
        return 1;
    }
    fcloseall();
    system("cd /d C: && erase err.txt /q");
    system("dir C:\ /b | find \"2.txt\" >> C:\err.txt");f.get();
    if(f.eof()){
        alarm("2.txt");
        return 1;
    }
    system("cd /d C:  && copy 1.txt+2.txt 3.txt ");
    fcloseall();
}

Автор: 586 2.6.2008, 18:02
Самый оптимальный - с помощью функций CreateFile, ReadFile и WriteFile.

Автор: RDC 2.6.2008, 21:02
586, согласен с Вами. Щас буду реализовывать. Потом код выложу.

Автор: 586 2.6.2008, 22:09
Правда, может быть проблема, что текстовые файлы будут с разной кодировкой (например, символ перевода строки будет не CRLF а LF). Тогда нужно использовать функции из стандартной библиотеки - fopen и т.п. открывая файл в текстовом режиме. По умолчанию fopen открывает файл в текстовом режиме.

Автор: jonie 3.6.2008, 11:14
жестоко. неучитывая то что сказал 586 решается это например так (быстрее чем с текстом возиться):
Код

    ifstream in("C:\\1.txt",ios::binary|ios::in);
    ofstream out("C:\\2.txt", ios::app|ios::binary);
    out<<in.rdbuf();

только я неособо вкурсе насчет размера in файла... нада почитать стандарт)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)