14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
1

Поменять местами содержимое файлов - C++ без использования третьего файла

04.09.2015, 17:56. Показов 4133. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!

Задача такая, поменять содержимое двух файлов без использования третьего файла. Эта задача была решена в теме по адресу Файл: Поменять местами содержимое файлов

Код следующий

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
vector <char> s1; // Объявляю массив символов (так как файл текстовый) неизвестной длины
    vector <char> s2; // неизвестной, так как непонятно, сколько будет символов и в том и в другом файле
 
    char *fname1 = "1.txt"; // имя 1-го файла
    char *fname2 = "2.txt"; // имя 2-го файла
    
 //ifstream - для чтения
 //ofstream - для записи
 
    // считываю содержимое 1-го файла  
    ifstream *in1 = new ifstream(); //  Может, создается новый массив? типа ifstream 
    in1->open(fname1, ios::binary); // с помощью "стрелки" обратились к функции открытия файла с именем 1.txt 
                                    // Открываем в двоичном режиме, чтобы не было ненужного преобразования данных
    
    //если файл не открыли, то вернет ошибку. Ф-ия fail() сообщает о локальной ощибке не открытия файла
    if(in1-> fail()){ //с помощью стрелки обратились к ф-ии fail(). Запись эквивалента if(!...){cout<<"Не шмогла открыть!"}
        cout << "file '" << fname1 << "' not found" << endl;
        exit(1); 
    } //
    
    //делать пока не достигнут конец файла. в конец файла 1 записать что-то (описанное в ф-и) get()
    // Функция get() поэлементно перебирает символы 
    while(!in1->eof()) s1.push_back(in1->get()); // с помощью стрелки обратились к ф-ии eof() и get()
                                                                  // а также в массив s1 записываем содержимое файла 1
    
    in1->close();  // хитро закрываем файл
    delete in1;    //А вот зачем удалять??? 
    // Видимо удаляется in1, так как он был "связан" со стрелкой, и 
    //может быть, in1 - это массив в котором хранится содержимое первого файла?  
 
    // считываю содержимое 2го файла
    ifstream *in2 = new ifstream(); //фактически делаем всё то же самое, только со вторым файлом 
    in2->open(fname2, ios::binary);
    if(in2->fail()) { cout << "file '" << fname2 << "' not found" << endl; exit(1); }
    while(!in2->eof()) s2.push_back(in2->get());
    in2->close();
    delete in2;//та же история, с непониманием этой строчки
 
    
    
    // записываю в 1-ый файл содержимое 2-го
    ofstream *on1 = new ofstream();
    on1->open(fname1, ios::binary);
    if(on1->fail()) { cout << "file '" << fname1 << "' not found" << endl; exit(1); }
    for(unsigned int i = 0; i < s2.size()-1; i++)
        *on1 << s2[i];
    on1->close();
    delete on1;
 
    // записываю во 2-ой файл содержимое 1-го
    ofstream *on2 = new ofstream();
    on1->open(fname2, ios::binary);
    if(on2->fail()) { cout << "file '" << fname2 << "' not found" << endl; exit(1); }
    for(unsigned int i = 0; i < s1.size()-1; i++)
        *on2 << s1[i];
    on2->close();
    delete on2;
 
    return 0;
}
Я попытался разобраться в коде, но до конца и до полной ясности не получилось.



Не могу понять, зачем строчка:

delete in1;

Правильно ли я понимаю структуру программы? Здесь мы с помощью "стрелки" обратились к функции открытия файла с именем 1 далее

C++ (Qt)
1
2
3
4
if(in1-> fail()){ //с помощью стрелки обратились к ф-ии fail(). Запись эквивалента if(!...){cout<<"Не шмогла открыть!"}
        cout << "file '" << fname1 << "' not found" << endl;
        exit(1); 
    }

C++ (Qt)
1
2
3
while(!in1->eof()) s1.push_back(in1->get()); //с помощью стрелки обратились к ф-ии eof() и get() 
    in1->close();  // хитро закрываем файл
    delete in1;    //А вот зачем удалять???

Может ли кто-нибудь подсказать, правильно ли я понимаю и зачем удалять в конце in1? Правильно ли я понимаю работу со стрелкой?
Заранее спасибо
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.09.2015, 17:56
Ответы с готовыми решениями:

Даны 2 текстовых файла A и B.Поменять местами содержимое этих файлов
Даны 2 текстовых файла A и B.Поменять местами содержимое этих файлов. Напишите пожалуйста))

Даны два файла А и В (тип элементов одинаковый). Поменять местами содержимое этих файлов.
Даны два файла А и В (тип элементов одинаковый). Поменять местами содержимое этих файлов.

Поменять местами содержимое файлов
Даны два файла А и В (тип элементов одинаковый). Поменять местами содержимое этих файлов. на...

Поменять местами содержимое файлов
Даны два файла произвольного типа. С помощью процедуры Rename поменять местами их содержимое. ...

13
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
04.09.2015, 18:32 2
Цитата Сообщение от Blitzor DDD Посмотреть сообщение
Не могу понять, зачем строчка:
delete in1;
Автор зачем-то создаёт поток ifstream в динамической памяти, ну и соответственно в конце её нужно освободить.
Цитата Сообщение от Blitzor DDD Посмотреть сообщение
Здесь мы с помощью "стрелки" обратились к функции открытия файла
Потому и стрелка, что указатель.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 18:36  [ТС] 3
Цитата Сообщение от nmcf Посмотреть сообщение
Сообщение от Blitzor DDD
Не могу понять, зачем строчка:
delete in1;
Автор зачем-то создаёт поток ifstream в динамической памяти, ну и соответственно в конце её нужно освободить.
Сообщение от Blitzor DDD
Здесь мы с помощью "стрелки" обратились к функции открытия файла
Потому и стрелка, что указатель.



Непонятно...
0
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
04.09.2015, 18:42 4
Вот здесь выделяется память через new:
C++
1
ifstream *in1 = new ifstream();
Соответственно в конце, когда in1 уже не нужен, её требуется освободить (delete). Хотя следовало сделать так:
C++
1
ifstream in1;
Тогда и delete не понадобился бы и были бы точки вместо стрелок.

Читай про выделение памяти, new/delete, если не понимаешь.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
04.09.2015, 18:42 5
Цитата Сообщение от Blitzor DDD Посмотреть сообщение
Непонятно...
Тут поможет хорошая книга по С++.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 18:44  [ТС] 6
Цитата Сообщение от nmcf Посмотреть сообщение
от здесь выделяется память через new:
Код C++Выделить код
1
ifstream *in1 = new ifstream();
Соответственно в конце, когда in1 уже не нужен, её требуется освободить (delete). Хотя следовало сделать так:
То есть можно сделать практичнее и проще? Было бы намного легче!
А не подскажете как?
0
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
04.09.2015, 19:25 7
Лучший ответ Сообщение было отмечено Blitzor DDD как решение

Решение

Вот проще:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
 
using namespace std;
 
int main()
{
    char *fname1 = "1.jpg";
    char *fname2 = "2.jpg";
    
    stringstream iss1, iss2;
    fstream ifs;
 
    ifs.open(fname1, ios::binary | ios::in);
    if (!ifs)
    {
        cout << "file '" << fname1 << "' not found" << endl;
        exit(1);
    }
    iss1 << ifs.rdbuf();
    ifs.close();
 
    ifs.open(fname2, ios::binary | ios::in);
    if (!ifs)
    {
        cout << "file '" << fname2 << "' not found" << endl;
        exit(1);
    }
    iss2 << ifs.rdbuf();
    ifs.close();
 
    ifs.open(fname1, ios::binary | ios::out);
    if (!ifs) { cout << "file '" << fname1 << "' not found" << endl; exit(1); }
    ifs << iss2.rdbuf();
    ifs.close();
 
    ifs.open(fname2, ios::binary | ios::out);
    if (!ifs) { cout << "file '" << fname2 << "' not found" << endl; exit(1); }
    ifs << iss1.rdbuf();
    ifs.close();
 
    system("pause");
    return 0;
}
1
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 20:06  [ТС] 8
Большое спасибо!

Добавлено через 14 минут
C++ (Qt)
1
 iss1 << ifs.rdbuf();
Я правильно понимаю, что ф-ия rdbuf() сначала считывает весь файл в строковую переменную iss1, а потом той же функцией

C++ (Qt)
1
ifs << iss2.rdbuf();
записываем из одного файла в другой. Так?

Нигде не нашел хорошего описания функции rdbuf() на русском языке

Правильно тут понимаю?
0
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
04.09.2015, 20:13 9
Примерно так, только iss1 не строка, а поток на основе строки. rdbuf() позволяет получить содержимое потока без интерпретации.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 20:21  [ТС] 10
А разве stringstream - это не класс? И тут разве не создается объект? так же как в ООП?
То есть, в принципе можно использовать read и write?

Вот я посмотрел тут литературу свою, НИГДЕ не нашел функцию rdbuf(). Как вот "прошариться" в использовании таких хитростей?
0
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
04.09.2015, 20:29 11
Да, класс. Потоки и есть классы. Что здесь такого?
read() и write() можно использовать, только это усложнит программу, понадобится вычислять длины файлов выделять память. rdbuf() намного проще.
Не нашёл? А где искал-то? Вот: http://www.cplusplus.com/refer... eam/rdbuf/
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 20:30  [ТС] 12
Цитата Сообщение от nmcf Посмотреть сообщение
Да, класс. Потоки и есть классы. Что здесь такого?
Да-да, вы правы, простите за мою тупость.

А вот это на английском, а я вот в Шилдте искал, в Липпмане, там не нашел, только на английском...
0
7784 / 6553 / 2982
Регистрация: 14.04.2014
Сообщений: 28,615
04.09.2015, 20:33 13
Ну в книгах же не описывают все функции до последней.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 20:35  [ТС] 14
Цитата Сообщение от nmcf Посмотреть сообщение
Ну в книгах же не описывают все функции до последней.
Да.. Вот читаю ту ссылку, которую Вы скинули, непросто понять, конечно.
Ну ладно, большое Вам спасибо за помощь!
0
04.09.2015, 20:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.09.2015, 20:35
Помогаю со студенческими работами здесь

Поменять местами содержимое файлов
Поменять местами содержимое файлов A и B использую вспомогательный файл. Не могу понять как делать...

Поменять местами содержимое файлов
Даны два файла А и В. Поменять местами содержимое этих файлов.

Поменять местами содержимое двух файлов
поменять местами содержимое двух текстовых файлов. помогите найти ошибку var f,f1,fo:text;...

Файл: Поменять местами содержимое файлов
Даны два файла А и В (тип элементов одинаковый). Поменять местами содержимое этих файлов


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru