Дан бинарный файл, заполненый действительными числами. Нужно без другого файла переставить положительные числа в начало, а все остальные в конец
Сказали, что код неправильный, помогите исправить
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <conio.h>
#include <string>
#include <fstream>
using namespace std;
int main() {
FILE* f1;
int i = 0;
double arr[10] = {-24.4, 12.5, 34.6, -1.5, -4.7, -13.5, -2.6, 12.5, 3.9, -0.5};
if ((f1 = fopen("1.dat", "rb")) == 0)
{
perror("Can't open file!");
}
fscanf(f1, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4], &arr[5], &arr[6], &arr[7], &arr[8], &arr[9], &arr[10]);
fclose(f1);
for (int i = 0; 1 < 10; i++)
{
if (arr[i] > 0)
{
for (int j = 0; j < i; j++)
{
if (arr[j] < 0)
{
int x = arr[i];
arr[i] = arr[j];
arr[j] = x;
}
}
}
}
f1 = fopen("1.dat", "wb+");
fwrite(&arr[10], sizeof(float), 10, f1);
fclose(f1);
}
Ответы (1 шт):
Автор решения: Harry
→ Ссылка
Как я понимаю, от вас хотят что-то типа этого — без затягивания всего файла в память... Просто иначе никакие seek/tell не нужны в принципе...
#include <iostream>
#include <iomanip>
#include <random>
#include <fstream>
using namespace std;
int main()
{
{ // Первая часть Марлезонского балета - создание файла
default_random_engine u{random_device{}()};
size_t size = uniform_int_distribution<>{100,20000}(u);
ofstream out("data",ios::binary);
for(size_t i = 0; i < size; ++i)
{
double d = uniform_real_distribution<>{-1e6,1e6}(u);
out.write(reinterpret_cast<char*>(&d),sizeof(d));
}
}
{ // Вторая часть Марлезонского балета - вывод файла
ifstream in("data",ios::binary);
cout << setprecision(10);
for(double d; in.read(reinterpret_cast<char*>(&d),sizeof(d));)
cout << d << " ";
cout << "\n----------\n\n";
}
{ // Третья часть Марлезонского балета - обработка файла
fstream f("data",ios::binary|ios::in|ios::out);
auto b = f.tellg();
f.seekg(-int(sizeof(double)),ios::end);
auto e = f.tellg();
do {
double db, de;
f.seekg(b);
while(b < e && f.read(reinterpret_cast<char*>(&db),sizeof(double)) && db > 0.0)
b = f.tellg();
while(b < e)
{
f.seekg(e);
if (!f.read(reinterpret_cast<char*>(&de),sizeof(double))) break;
if (de > 0.0) break;
e -= sizeof(double);
}
if (b < e)
{
f.seekp(b);
f.write(reinterpret_cast<char*>(&de),sizeof(double));
b += sizeof(double);
f.seekp(e);
f.write(reinterpret_cast<char*>(&db),sizeof(double));
e -= sizeof(double);
}
} while(b < e);
}
{ // Четвертая часть Марлезонского балета - вывод файла
ifstream in("data",ios::binary);
cout << setprecision(10);
for(double d; in.read(reinterpret_cast<char*>(&d),sizeof(d));)
cout << d << " ";
cout << "\n----------\n\n";
}
}
Если можно весь файл всосать в память - еще проще:
{ // Третья часть Марлезонского балета - обработка файла
fstream f("data",ios::binary|ios::in|ios::out);
f.seekg(0,ios::end);
auto e = f.tellg();
vector<double> v(e/sizeof(double));
f.seekg(0,ios::beg);
f.read(reinterpret_cast<char*>(v.data()),e);
partition(v.begin(),v.end(),[](double d){ return d > 0; });
f.seekp(0,ios::beg);
f.write(reinterpret_cast<char*>(v.data()),e);
}