Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.12.2009, 19:47   #1
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию Обращение к двоичным файлам

Помогите разобраться, задача такая:
В двоичном файле поменять местами наибольшее и наименьшее вещественное значение.
Написал код, ошибок компилятор не выдает, кроме предупреждения, что то о ненадежной функции g.
Но строки которые должны поменять в файле наибольшее на наименьшее значение почемуто не работают, они в файле ничего не меняют.
Код:
#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	
	int i,n,imax,imin;
	double *a, *b, max,min;
	FILE *g;

	// Открытие файла и считывание в массив а
	g=fopen("C:\\abc.dat", "rb");
	fread(&n, sizeof(int),1,g);// Первое значение в файле указывает количество чисел в файле
	a=new double [n];
	fread(a, sizeof(double),n,g);

	// Вывод на консоль полученного массива
	for (i=0; i<n;i++)
		cout<<a[i]<<"\t";
	
	// Поиск наибольшего и наименьшего значения и их индексов
	max=*(a); imax=0;
	min=*(a); imin=0;
	for (i=0; i<n;i++)
	{
		if (*(a+i)>max)
		{
			max=*(a+i); imax=i;
		}
		if (*(a+i)<min)
		{
			min=*(a+i); imin=i;
		}
	}

	// Вывод на консоль найденных значений
cout<<"\n";
cout<<"max="<<max<<"\n";
cout<<"min="<<min<<"\n";
cout<<"imax="<<imax<<"\n";
cout<<"imin="<<imin<<"\n";

// Запись в двоичный файл максимального значения вместо минимального и наоборот
// Как раз эти строки и не работают. Почему?????

fseek (g,sizeof(int)+imax*sizeof(double),SEEK_SET); // Замена максимального значения на минимальное
fwrite (&min, sizeof(double),1,g);

fseek (g,sizeof(int)+imin*sizeof(double),SEEK_SET); // Замена минимального значения на максимальное
fwrite (&max, sizeof(double),1,g);

fclose(g);
delete []a;

// Вывод на консоль содержимого двоичного файла (где должно быть вместо max min и наоборот). 
// Массив выводится таким же как и в первой части кода, без изменений. 

        FILE *c;
	c=fopen("C:\\abc.dat", "rb");
        fread(&n, sizeof(int),1,c);
	b=new double [n];
	fread(b, sizeof(double),n,c);
	
        for (i=0; i<n;i++)
		cout<<b[i]<<"\t";
		
	cout<<endl;
	fclose(g);
        delete []a;
	return 0;

}
Заранее спасибо
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол

Последний раз редактировалось atenon; 08.12.2009 в 20:42.
atenon вне форума Ответить с цитированием
Старый 09.12.2009, 20:51   #2
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

В предыдущем коде забыл вставить создание файла "abc".
Код:
#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	
	int i,n,imax,imin;
	double *a, *b, max,min;

                 // Создание файла "авс"
	FILE *f;
	int r;
	double k;
	f=fopen("C:\\abc.dat", "wb");
	cout<<"r=";
	cin>>r;
	fwrite(&r, sizeof(int),1,f); // Первое значение файла указывает количество элементов
	
        // Ввод значений с консоли в файл
        for (i=0; i<r;i++)
	     {
		cout<<"k=";
		cin>>k;
		fwrite(&k, sizeof(double),1,f);
	     }
	fclose(f);




	FILE *g;

	// Открытие файла и считывание в массив а
	g=fopen("C:\\abc.dat", "rb");
	fread(&n, sizeof(int),1,g);// Первое значение в файле указывает количество чисел в файле
	
         // Считывание значений из файла в массив
        a=new double [n];
	fread(a, sizeof(double),n,g);

	// Вывод на консоль полученного массива
	for (i=0; i<n;i++)
		cout<<a[i]<<"\t";
	
	// Поиск наибольшего и наименьшего значения и их индексов
	max=*(a); imax=0;
	min=*(a); imin=0;
	for (i=0; i<n;i++)
	{
		if (*(a+i)>max)
		     {
			max=*(a+i); imax=i;
		       }
		if (*(a+i)<min)
		       {
			min=*(a+i); imin=i;
		        }
	}

	// Вывод на консоль найденных значений
cout<<"\n";
cout<<"max="<<max<<"\n";
cout<<"min="<<min<<"\n";
cout<<"imax="<<imax<<"\n";
cout<<"imin="<<imin<<"\n";

// Запись в двоичный файл максимального значения вместо минимального и наоборот
// Как раз эти строки и не работают. Почему?????

fseek (g,sizeof(int)+imax*sizeof(double),SEEK_SET); // Переход к максимальному элементу файла
fwrite (&min, sizeof(double),1,g);  // Запись минимального значения на место максимального

fseek (g,sizeof(int)+imin*sizeof(double),SEEK_SET); // Переход к минимальному элементу файла
fwrite (&max, sizeof(double),1,g); // Запись максимального значения на место минимального

fclose(g);
delete []a;

// Вывод на консоль содержимого двоичного файла (где должно быть вместо max min и наоборот). 
// Массив выводится таким же как и в первой части кода, без изменений. 

        FILE *c;
	c=fopen("C:\\abc.dat", "rb");
        fread(&n, sizeof(int),1,c);
	b=new double [n];
	fread(b, sizeof(double),n,c);
	
        for (i=0; i<n;i++)
		cout<<b[i]<<"\t";
		
	cout<<endl;
	fclose(g);
        delete []a;
	return 0;

}
Хоть убей не могу найти ошибку, подскажите пожалуйста.
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол

Последний раз редактировалось atenon; 10.12.2009 в 18:16.
atenon вне форума Ответить с цитированием
Старый 17.12.2009, 16:39   #3
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

Нашел ошибку. В функции открытия файла вместо "rb+" я написал "rb"
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол
atenon вне форума Ответить с цитированием
Старый 17.12.2009, 19:19   #4
RoS
Форумчанин
 
Аватар для RoS
 
Регистрация: 13.12.2009
Сообщений: 272
По умолчанию

Теперь можешь поднять рейтинг себе самому
Скромный воспрос - почему предпочитаешь функции Си, а не потоки?
Я не навязываю, просто интересуюсь
Если я помог вам - порадуйте меня, нажмите на весы слева
RoS вне форума Ответить с цитированием
Старый 17.12.2009, 19:59   #5
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

Цитата:
Скромный воспрос - почему предпочитаешь функции Си, а не потоки?
Я думал cin и cout как раз и есть объекты-потоки, а printf и skanf функции ввода вывода.
Я недавно начал учить с++ так что возможно я не правильно понял суть вопроса. Может просто я до этой темы еще не дошёл.
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол
atenon вне форума Ответить с цитированием
Старый 17.12.2009, 20:10   #6
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Цитата:
Я думал cin и cout как раз и есть объекты-потоки, а printf и skanf функции ввода вывода.
Я недавно начал учить с++ так что возможно я не правильно понял суть вопроса. Может просто я до этой темы еще не дошёл.
cin и cout действителньо потоки, причем потоки ввода\вывода, только выводят они на экран, а есть такие же потоки для вывода\ввода в файлы (ofstream - вывод ifstream - ввод fstream - ввод\вывод). ТОлько тут чуть-чуть иначе все (вообще, если будешь разбираться с ООП, то все поймешь, а я кратенько объясню с чем их едят).

Код:
int a=50;
ofstream  file1("a.txt")//создаем поток вывода file1
file1>>a;//записываем в текстовый файл текст "50"

ofstream  file2("b.txt", ios::binary)//создаем поток вывода file2, на этот раз двоичный
write((char *)&a, sizeof(int));//записываем все, что по адресу переменной a в файл (интерпретируя это как однобайтовые символы, которых аш sizeof(int), т.е. 4 байта(4 штуки)).
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс
ROD вне форума Ответить с цитированием
Старый 17.12.2009, 21:06   #7
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

Спасибо теперь понял о каких потоках идет речь.
Цитата:
ofstream file2("b.txt", ios::binary)
write((char *)&a, sizeof(int));
Только смущает расширение txt (файл должен быть двоичным).
И не совсем понятно (char *). Преобразование к символьнуму типу?
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол

Последний раз редактировалось atenon; 17.12.2009 в 21:08.
atenon вне форума Ответить с цитированием
Старый 17.12.2009, 21:13   #8
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Цитата:
Только смущает расширение txt (файл должен быть двоичным).
вообще файлу абсолютно все равно что в нем находится (а потокам вообще плевать на расширение файла, его может не быть вовсе, или быть какое-то абстрактное типа "bla-bla-bla.bukovki").

Цитата:
И не совсем понятно (char *). Преобразование к символьнуму типу?
Да, это преобразование к символьному типу. Зачем преобразовывать к символьному типу я, честно говоря, не знаю, скорее всего просто, что бы считывать из памяти и записывать в файл по одному байту. (ну и так же из файла в память читать).
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс

Последний раз редактировалось ROD; 17.12.2009 в 21:15.
ROD вне форума Ответить с цитированием
Старый 17.12.2009, 23:58   #9
RoS
Форумчанин
 
Аватар для RoS
 
Регистрация: 13.12.2009
Сообщений: 272
По умолчанию

Цитата:
Сообщение от ROD Посмотреть сообщение
вообще файлу абсолютно все равно что в нем находится (а потокам вообще плевать на расширение файла, его может не быть вовсе, или быть какое-то абстрактное типа "bla-bla-bla.bukovki").


Да, это преобразование к символьному типу. Зачем преобразовывать к символьному типу я, честно говоря, не знаю, скорее всего просто, что бы считывать из памяти и записывать в файл по одному байту. (ну и так же из файла в память читать).
Абсолютно прав, методы read и write работают с байтами, они по сути, переносят байты из памяти в файл, а char, как известно, занимает какраз один байт...Еще можно пользоваться примерно так

Код:
char buf[] = "Simple text"; //информация для записи в файл
file.write(reinterpret_cast<char*>(buf), sizeof(buf)); //записываем в двоичном виде
А насчет txt - да попробуй открой его, увидишь много разных каракулей, блокнот будет пытаться преобразовать двоичные данные в текст, естественно тщетно
Если я помог вам - порадуйте меня, нажмите на весы слева
RoS вне форума Ответить с цитированием
Старый 18.12.2009, 08:26   #10
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

Цитата:
Абсолютно прав, методы read и write работают с байтами, они по сути, переносят байты из памяти в файл, а char, как известно, занимает какраз один байт...Еще можно пользоваться примерно так
То есть преобразование происходит только потому, что методы read и write работают с однобайтовыми данными?
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол
atenon вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача по Файлам на Си++ Клеом Помощь студентам 2 15.12.2009 12:47
Доступ к файлам Gerzs Общие вопросы Delphi 10 09.10.2009 21:21
Вопрос по файлам Molotoff Общие вопросы C/C++ 4 20.06.2009 21:58
C++. Последовательное обращение к файлам с расширением Парсифаль Помощь студентам 8 06.05.2009 21:54
Работа с двоичным кодом lacost Общие вопросы Delphi 7 19.11.2008 10:38