Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460

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

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

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

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

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

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
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.09.2015, 17:56
Ответы с готовыми решениями:

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

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

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

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



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

Читай про выделение памяти, new/delete, если не понимаешь.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
04.09.2015, 18:42
Цитата Сообщение от Blitzor DDD Посмотреть сообщение
Непонятно...
Тут поможет хорошая книга по С++.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 18:44  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
от здесь выделяется память через new:
Код C++Выделить код
1
ifstream *in1 = new ifstream();
Соответственно в конце, когда in1 уже не нужен, её требуется освободить (delete). Хотя следовало сделать так:
То есть можно сделать практичнее и проще? Было бы намного легче!
А не подскажете как?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
04.09.2015, 19:25
Лучший ответ Сообщение было отмечено 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  [ТС]
Большое спасибо!

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

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

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

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

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

А вот это на английском, а я вот в Шилдте искал, в Липпмане, там не нашел, только на английском...
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
04.09.2015, 20:33
Ну в книгах же не описывают все функции до последней.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
04.09.2015, 20:35  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Ну в книгах же не описывают все функции до последней.
Да.. Вот читаю ту ссылку, которую Вы скинули, непросто понять, конечно.
Ну ладно, большое Вам спасибо за помощь!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.09.2015, 20:35
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru