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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.02.2009, 18:01   #1
Maksitron
 
Регистрация: 11.02.2009
Сообщений: 4
Печаль Чтение Бинарных Файлов

Всем привет . Я лично програмаю на Делфи, но вот случилась беда и пришлось разобрать код на C++ ( Visual C++ 6 ). - Нужно как бы перевести Сишный код для Делфи. И тут возникло пару запарок: с функциями чтения бинарных файлов я не знаком((( поэтому прошу Экспертов ( и просто знающих людей ) обьяснить мне пару функций - что они делают , какие у них аргументы

Вот функции:
1) inFile.good() -( как я понимаю счётчик конца файла? )
2)inFile.seekg( Position ); - ( как я понимаю перемещает каретку на нужную позицию в файле ? )
3) char Ch;
inFile >> Ch; - ( как я понимаю считывает 1 байт из файла в переменную типа Char ?)
4) inFile.tellg() - ( возвращает позицию каретки в файле? )
5) inFile.ignore(1); - тут даже предположений нет - хз что она делает (((


А вот код всей функции :

Код:
bool remMesh::LoadFromFile(const rStr &Filename)
{
	streampos NextNode = 0, Tmp, Face_p, Vertex_p;
	SingleGeomNode N;
	int i, Hdr = 0;
	char Ch;

	ifstream inFile(Filename.c_str(), ios::in | ios::binary | ios::nocreate);
	// if file open error
	if (!inFile) return false;
	// Else read file and save data to vector MeshVerts
	while (inFile.good())
	{
		N.WithMtl = false;
		N.WithTexture = false;
		N.TextureName = "";
		// read num faces and vertexes
		inFile.seekg(NextNode + 2);
		
		inFile.read((char *)&Tmp, 4);
		N.MeshVerts.resize(Tmp);
		
		inFile.read((char *)&Tmp, 4);
		N.MeshTVerts.resize(Tmp);
		
		inFile.read((char *)&Tmp, 4);
		N.MeshFaces.resize(Tmp);

		// process with data
		inFile.read((char *)&NextNode, 4);
		
		inFile.seekg(inFile.tellg() + 2);
		


		// Reed material data
		inFile.read((char *)&Vertex_p, 4);
		// Check if material present
		
		inFile.read((char *)&Hdr, 2);
		inFile.seekg(inFile.tellg() - 2)
			;
		if (Hdr != ID_VERTEX_HEADER)
		{
			N.WithMtl = true;
			// read material components
			inFile.read((char *)&N.mtlAmbient.C[0], sizeof(float) * 3);
			inFile.read((char *)&N.mtlDiffuse.C[0], sizeof(float) * 3);
			inFile.read((char *)&N.mtlSpecular.C[0], sizeof(float) * 3);
			// read Shininess
			inFile.read((char *)&N.mtlSpecular.C[3], sizeof(float));
			// read filename
			do {
				inFile >> Ch;
				N.TextureName += Ch;
			} while(Ch != 0);
			N.TextureName.resize(N.TextureName.size() - 1);
		}
		
		// Read Vertex data.
		inFile.seekg(inFile.tellg() + 2);
		
		inFile.read((char *)&Face_p, 4);
		
		
		while (inFile.good() && (inFile.tellg() < NextNode))
		{
			for (i = 0; i < N.MeshVerts.size(); i++)
			{
				inFile.read((char *)&N.MeshVerts[i].vert[0], sizeof(float) * 3);
				inFile.read((char *)&N.MeshVerts[i].normal[0], sizeof(float) * 3);
			}
			// Read Texture vertex data
			inFile.read((char *)&Tmp, 2);
			if (Tmp == ID_TVERTEX_HEADER)
			{
				for (i = 0; i < N.MeshTVerts.size(); i++)
				{
					inFile.read((char *)&N.MeshTVerts[i].vert[0], sizeof(float) * 2);
				}
			}
			else
				inFile.seekg(inFile.tellg() - 2);

			// Skip Face data block header
			inFile.read((char *)&Tmp, 2);
			// Read face data
			for (i = 0; i < N.MeshFaces.size(); i++)
			{
				if (N.MeshTVerts.size() != 0)
					inFile.read((char *)&N.MeshFaces[i].VertIndex[0], sizeof(float) * 6);
				else
					inFile.read((char *)&N.MeshFaces[i].VertIndex[0], sizeof(float) * 3);
			}

			inFile.ignore(1);
		}
		Model.push_back(N);
	}
	return true;
}
Модератор: тег CODE

Последний раз редактировалось MaTBeu; 23.02.2009 в 19:00.
Maksitron вне форума Ответить с цитированием
Старый 23.02.2009, 19:11   #2
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Первые 2, 3 и 4 пункты правильно вы определили.
Пятый пункт - это пропуск определенного количества символов относительно текущей позиции в файле.
Первый пункт - это определение состояния потока для установки флагов. Флаги бывают нескольких типов ios::badbit, ios::goodbit, ios::failbit и ios::eofbit.
Флаги показывают состояние потока если goodbit - значит поток в норме.
badbit - в потоке ошибки.
failbit - приблизительно тоже самое что и badbit
eofbit - конец потока.
MaTBeu вне форума Ответить с цитированием
Старый 23.02.2009, 19:31   #3
Maksitron
 
Регистрация: 11.02.2009
Сообщений: 4
По умолчанию

inFile.ignore(1); - т.е. (простите пож за откровенную тупость(= ) в данном случае это переход на 1 байт вперед в файле?

Тогда возникает вопрос:
Почему нельзя написать что то типа inFile.seekg( inFile.tellg() + 1 );
В чем же тогда получится отличие?

З.Ы. В коде получается что используют как
inFile.seekg( inFile.tellg() + 1 ); так и inFile.ignore(1); .
З.Ы.Ы. Еще раз простите за глупые вопросы просто из всех форумов на которых я вывесил эту тему понятно и доходчиво ответили только вы.
Maksitron вне форума Ответить с цитированием
Старый 23.02.2009, 19:54   #4
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Нет, это не перемещение указателя. Эта функция указывает сколько байтов необходимо пропустить при следующем чтении. Тоесть вы пиешете inFile.ignore(1);, а потом читаете из файла, то считается не тот байт, на котором указатель файла, а тот, что за ним.
MaTBeu вне форума Ответить с цитированием
Старый 23.02.2009, 20:17   #5
Maksitron
 
Регистрация: 11.02.2009
Сообщений: 4
По умолчанию

Мда... мне начинает казаться что я безнадёжен
Из вашего ответа я понял что inFile.ignore(1); при следующем чтении из файла (float a; inFile.read((char *)&a, sizeof(float) ); ) делает так что считывается данные не с текущей позиции указателя, а с позиции = (позиция указателя - 1 ). Я правильно вас понял?

Если не трудно могли бы вы обьяснить зачем эту функцию вообще всунули в этот цикл:
(И можно ли её заменить как нить на комбинацию этих функций:
inFile.seekg( Значение );
inFile.tellg() )


Код:
while (inFile.good() && (inFile.tellg() < NextNode))
		{
			for (i = 0; i < N.MeshVerts.size(); i++)
			{
				inFile.read((char *)&N.MeshVerts[i].vert[0], sizeof(float) * 3);
				inFile.read((char *)&N.MeshVerts[i].normal[0], sizeof(float) * 3);
			}
			// Read Texture vertex data
			inFile.read((char *)&Tmp, 2);
			if (Tmp == ID_TVERTEX_HEADER)
			{
				for (i = 0; i < N.MeshTVerts.size(); i++)
				{
					inFile.read((char *)&N.MeshTVerts[i].vert[0], sizeof(float) * 2);
				}
			}
			else
				inFile.seekg(inFile.tellg() - 2);

			// Skip Face data block header
			inFile.read((char *)&Tmp, 2);
			// Read face data
			for (i = 0; i < N.MeshFaces.size(); i++)
			{
				if (N.MeshTVerts.size() != 0)
					inFile.read((char *)&N.MeshFaces[i].VertIndex[0], sizeof(float) * 6);
				else
					inFile.read((char *)&N.MeshFaces[i].VertIndex[0], sizeof(float) * 3);
			}

			inFile.ignore(1);
		}
P.S. Буду вечно вам благодарен

P.S. у нас дан бинарный файл, он состоит из блоков содержащий информацию каждый блок имеет указатель на его начало (т.е. позиция в байтах).

В этом цикле мы считываем информацию из блока пока инфа считывается без ошибок и пока не достигнут конец первого блока и начало второго.

Последний раз редактировалось Maksitron; 23.02.2009 в 20:28.
Maksitron вне форума Ответить с цитированием
Старый 23.02.2009, 21:32   #6
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Ну наверное в конце каждого блока есть какой-то символ (или байт), обозначающий конец блока. Тоесть мы считали нужную нам информацию, а после чтения этого блока, нам нужно начать читать следующий, но у нас в текущем блоке лежит еще символ конца блока.
Поэтому при следующем чтении информация будет формально считываться вместе с тем символом, но благодаря функции ignore(1) записываться будет со следующего символа после этого.

В принципе вы можете просто переместить указатель на 1 байт вперед и все.
MaTBeu вне форума Ответить с цитированием
Старый 23.02.2009, 21:37   #7
Maksitron
 
Регистрация: 11.02.2009
Сообщений: 4
По умолчанию

окей - спасибо огромное!
Maksitron вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Посимвольное чтение нетипизированных файлов Wi1D Помощь студентам 4 03.10.2010 16:13
Помогите отсортировать массив методом бинарных вставок zhorzh2407 Помощь студентам 1 19.11.2008 17:19
Чтение файлов с диска Wolf-alone Общие вопросы C/C++ 1 17.09.2008 10:05
Нужна помощь: выбор файлов исходя из имени файлов Antik163RUS Помощь студентам 4 19.06.2008 21:20
Чтение MP3 файлов из папки PAVEL315 Общие вопросы Delphi 1 03.03.2007 13:33