@Vlad_Ilnitskiy

Как обработать двоичный файл в с++?

Здравствуйте! Условие задачи такое: задан двоичный файл целых чисел, все простые числа записать в другой файл, во втором файле поменять местами 2 наименьших числа, не используя массивы. По сути, проблема в маленьком кусочке кода, который ставит курсор в файле в нужное место:
fseek (f, sizeof(int)+min11*sizeof (int), SEEK_SET);
  fwrite (&min2, sizeof(int), 1, f);
  fseek(f, sizeof(int)+min22*sizeof (int), SEEK_SET);
  fwrite (&min1, sizeof (int), 1, f);

Бьюсь уже несколько дней, не могу понять в чем проблема. На всякий случай, вот код целиком:
#include <iostream>
#include <fstream>
#include <cstdio>

using namespace std;
int create_file ()
{
	FILE *f; int n, i, *a;
	cout<<"n="; cin>>n;
	a=new int [n];
	for (i=0; i<n; i++) {
	 cout<<"a["<<i<<"]=";  cin>>a[i]; cout<<"\n"; }
	f=fopen("abc.dat", "wb");
	fwrite(&n, sizeof(int), 1, f);
	fwrite(a, sizeof(int), n, f);
	fclose(f);
	cout<<"\nCOMPLETED";
	return 0;
}
bool Prostoe (int n)
{
    int k; bool Pr;
		 for (k=2, Pr=true; k <= n/2; k++)
		  if (n%k==0) 
		  {Pr=false; break;}
     return Pr;
}

int pr_file()
{
	FILE *f;
	int i, n, *a;
	f=fopen ("abc.dat", "rb");
	fread(&n, sizeof (int), 1, f);
	cout<<n<<endl;
	a=new int [n];
	fread (a, sizeof (int), n, f);
	fclose(f);
	f=fopen ("abc1.dat", "wb");
	for (i=0; i<n; i++) 
        if (Prostoe(a[i]))  {
              fwrite(&a[i], sizeof (int), 1, f); 
              cout<<"a["<<i<<"]="<<a[i]<<endl;}
    fclose (f);
    cout<<"\nCOMPLETED\n";
	return 0;
}

int delete_file ()
{
	FILE *f; int a,min2,min1, pr=0,min11, min22;
	f=fopen("abc1.dat", "rb");
	for(pr=0;!feof(f); pr++) {
	fread (&a, sizeof(int), 1, f);
      if (pr==0) {min1=a;min11=pr;} 
      else if (pr==1){ if (a<min1) {min2=min1;min22=min11;min1=a; min11=pr;}
       else {min2=a; min22=pr;}}
      else if (a<min1) {min2=min1;min22=min11; min1=a; min11=pr;}
      else if (a<min2) {min2=a;min22=pr;}}
      fclose(f);
    f=fopen("abc1.dat", "ab+");
   cout<<"min1="<<min1<<endl;
   cout<<"min2="<<min2<<endl;
   cout<<"min11="<<min11<<endl;
   cout<<"min22="<<min22<<endl; 
  fseek (f, sizeof(int)+min11*sizeof (int), SEEK_SET);
  fwrite (&min2, sizeof(int), 1, f);
  fseek(f, sizeof(int)+min22*sizeof (int), SEEK_SET);
  fwrite (&min1, sizeof (int), 1, f);
  fclose (f);
  cout<<"\nCOMPLETED\n";
  return 0;
}

int read_file()
{
	FILE *f;
	int  a;
	f=fopen("abc1.dat", "rb");
	while (!feof(f)) {
	fread (&a, sizeof(int), 1, f);
	cout<<"a="<<a<<"\n"; }
	fclose(f);
	 cout<<"\nCOMPLETED\n";
	return 0;
}

int main(int argc, char **argv)
{
	int i;
	cout<<"1. Create file\n2. Search simple numbers\n3. Delete 2 min numbers\n4. Read file\n0. Esc\n";
	cin>>i;
	for (;i!=0; cin>>i) {
	if (i==1)
	 create_file();
    if (i==2)
     pr_file();
    if (i==3)
     delete_file();
    if (i==4)
     read_file(); }
	return 0;
}
  • Вопрос задан
  • 2980 просмотров
Решения вопроса 2
icelaba
@icelaba
Знаю и умею всё
зачем вообще в fseek sizeof(int)+?
а если минимум по смещению 0 вы все равно будете писать по смещению 4?
Ответ написан
@encyclopedist
Для того, чтобы изменять файл в произвольном месте без уничтожения содержимого, нужно применять режим "r+" при открытии
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@encyclopedist
Проблема в том что в режиме "a+" запись всегда происходит в конец файла.
Цитата из man fopen:
a+ Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.

Вопрос по теме на SO:
stackoverflow.com/questions/3645123/opening-a-file...
Стандартные средства языка С не предоставляют возможности писать в произвольное место в файле. Вам нужно изменить алгоритм, либо пользоваться ками-то более низкоуровневыми и платформо специфичными средствами.
Ответ написан
icelaba
@icelaba
Знаю и умею всё
Начните с того что проверка на простое число достаточно гнать цикл до (корня из n) +1 :-) а то вас преподаватель или куда это надо не поймет
Ответ написан
@v_prom
@encyclopedist, стандартные средства языка си, позволяют это делать.
функция fseek().
Нужно только подобрать правильный режим.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы