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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 08.01.2012, 00:25   #1
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию Все еще потоки...

вот две функции:
Код:
	void Show(){
		ifstream ifst(Name.c_str());
		Class a;
		int Length;
		int NumberOfItems;
		int arraw;

		ifst.seekg (0, ios::end);
		Length = ifst.tellg();
		ifst.seekg(0, ios::beg);

		NumberOfItems=Length/(sizeof(int)+sizeof(Class));

		cout<<"Number of items: "<<NumberOfItems<<"\n";
			for (int i=0; i<NumberOfItems; i++){
				ifst.read(reinterpret_cast<char*>(&arraw),sizeof(int));
				ifst.seekg(arraw, ios::beg);
				ifst.read(reinterpret_cast<char*>(&a),sizeof(Class));
				cout<<a<<" ";
			}
			cout<<"\n";
	};

	void Sort(){};

	void Download(Box<Class>BOX[], int &BCounter){
		cout<<"What is the next item in the list?: ";
		cin>>BOX[BCounter];
		if(Begin!=0){BOX[BCounter].Next=Begin;}
		Begin=&BOX[BCounter];
		if ((BCounter+1)==11){Refresh(); BCounter=0;} //если массив элементов переполнен. все элементы записать в файл и писать следующие элементы поверх старых.
		else {BCounter=BCounter+1;}
		
	};

Код:
void Refresh(){

		int Length, Number;
		ifstream ifst(Name.c_str());
		ifst.seekg (0, ios::end);
		Length=ifst.tellg(); // длинна уже записаного файла
		ifst.seekg (0, ios::beg);
        Number=(Length/(sizeof(int)+sizeof(Class)));   // количество уже записанных элементов находиться по принципу|| вся длинна файла делиться на сумму занимаймую одним файловым указателем типа инт и одним элементом
		
		///////////////////////////////////////////////
		int arrow; // указатель на тот байт с которого начинаеться запись элемента
		Box<Class>* Index;
		Index=Begin;
		ofstream ofst;
		ofst.open(Name.c_str()); // создание потока записи в файл
		for (;Index->Next!=NULL;){
			Number=Number+1;
			arrow=1+Number*sizeof(int)+(Number-1)*sizeof(Class);
			ofst.write(reinterpret_cast<char*>(&arrow),sizeof(int)); //записывает файловый указатель
			ofst.write(reinterpret_cast<char*>(&(Index->T)),sizeof(Class));   // Функция записывает все элементы List в файл до моментка когда Next=Null
			Index=Index->Next;
		}
		Number=Number+1;
		arrow=1+Number*sizeof(int)+(Number-1)*sizeof(Class);
        ofst.write(reinterpret_cast<char*>(&arrow),sizeof(int));
		ofst.write(reinterpret_cast<char*>(&(Index->T)),sizeof(Class));
		ofst.close(); // закрытие потока
	}
};
файл устроен таким образом: [УказательНаСледующийЭлемент][Элемент][УказательНаСледующийЭлемент][Элемент][УказательНаСледующийЭлемент][Элемент]...

вообщем то со стороны кажется глупо, зачем нужны указатели, это для удобства сортировки, удаления и т.п, вообщем так надо.

указатель рассчитываю так: 1+(номер элемента)*sizeof(int)+(номер элемента-1)*sizeof(Class);

вроде бы все логично, но читается из файла всякая ерунда (Количество записанных элементов находиться правильно а вот сами элементы увы)

Скорее всего в логике Show() ошибка, но засечь не могу(
pinkiller вне форума Ответить с цитированием
Старый 08.01.2012, 00:28   #2
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

pinkiller

Все еще потоки...

чё за потоки-то? судя по портянке выше - потоки сознания... :D

ты по-человечески объясни, чего ты хочешь?
Rififi вне форума Ответить с цитированием
Старый 08.01.2012, 00:39   #3
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию

функция Refresh записывает в файл
функция Show читает

хочу чтобы Show читала что записано)

Но не просто подряд а по особому правилу)

в начале файла стоит интовый указатель на нужный байт с которого надо читать элемент. то есть для первого элемента 5 (4 байта занимает сам указатель) хочу прочитать эту пятерку в переменную arraw что получается успешно, а потом имея эту 5 прочитать значения начинающееся с 5го байта:
Код:
ifst.seekg(arraw, ios::beg);
	 ifst.read(reinterpret_cast<char*>(&a),sizeof(Class));
         cout<<a<<" ";
pinkiller вне форума Ответить с цитированием
Старый 08.01.2012, 01:09   #4
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию

Я тупой... откровенно тупой...
Код:
ifst.seekg(arraw-1, ios::beg);
считать надо с 0!!! а не с 1...

Я потратил на это с 12 ночи до 4... ^^
pinkiller вне форума Ответить с цитированием
Старый 08.01.2012, 01:15   #5
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию

Вот улучшенный код. но проблема в том что он корректен на int и не корректен на char хотя все вроде продумано для любых данных.
Может кто подкинет мысль в чем может быть дело?

Код:
template <class Class> 
class List{

public: 
	Box<Class>* Begin;
	string Name;
	List(){Begin=0;};
	void Show(){
		ifstream ifst;
		ifst.open(Name.c_str(), ios::binary);
		Class a;
		int Length;
		int NumberOfItems;
		int arraw;

		ifst.seekg (0, ios::end);
		Length = ifst.tellg();
		ifst.seekg(0, ios::beg);

		NumberOfItems=Length/(sizeof(int)+sizeof(Class));

		cout<<"Number of items: "<<NumberOfItems<<"\n";
			for (int i=0; i<NumberOfItems; i++){
				ifst.read(reinterpret_cast<char*>(&arraw),sizeof(int));
				ifst.seekg(arraw-1, ios::beg);
				ifst.read(reinterpret_cast<char*>(&a),sizeof(Class));
				cout<<a<<" ";
			}
			cout<<"\n";
	};

	void Sort(){};

	void Download(Box<Class>BOX[], int &BCounter){
		cout<<"What is the next item in the list?: ";
		cin>>BOX[BCounter];
		if(Begin!=0){BOX[BCounter].Next=Begin;}
		Begin=&BOX[BCounter];
		if ((BCounter+1)==11){Refresh(); BCounter=0;} //если массив элементов переполнен. все элементы записать в файл и писать следующие элементы поверх старых.
		else {BCounter=BCounter+1;}
		
	};

	void Remove(){};

	void Refresh(){

		int Length, Number;
		ifstream ifst(Name.c_str());
		ifst.seekg (0, ios::end);
		Length=ifst.tellg(); // длинна уже записаного файла
		ifst.seekg (0, ios::beg);
        Number=(Length/(sizeof(int)+sizeof(Class)));   // количество уже записанных элементов находиться по принципу|| вся длинна файла делиться на сумму занимаймую одним файловым указателем типа инт и одним элементом
		
		///////////////////////////////////////////////
		int arrow; // указатель на тот байт с которого начинаеться запись элемента
		Box<Class>* Index;
		Index=Begin;
		ofstream ofst;
		ofst.open(Name.c_str(), ios::app); // создание потока записи в файл
		for (;Index->Next!=NULL;){
			Number=Number+1;
			arrow=1+Number*sizeof(int)+(Number-1)*sizeof(Class);
			ofst.write(reinterpret_cast<char*>(&arrow),sizeof(int)); //записывает файловый указатель
			ofst.write(reinterpret_cast<char*>(&(Index->T)),sizeof(Class));   // Функция записывает все элементы List в файл до моментка когда Next=Null
			Index=Index->Next;
		}
		Number=Number+1;
		arrow=1+Number*sizeof(int)+(Number-1)*sizeof(Class);
        ofst.write(reinterpret_cast<char*>(&arrow),sizeof(int));
		ofst.write(reinterpret_cast<char*>(&(Index->T)),sizeof(Class));
		ofst.close(); // закрытие потока
	}
};
pinkiller вне форума Ответить с цитированием
Старый 08.01.2012, 13:21   #6
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Код:
int Length;   //<--- обрати внимание на тип данных
		int NumberOfItems;
		int arraw;

		ifst.seekg (0, ios::end);
		Length = ifst.tellg();
Дело в том, что если размер файла окажется слишком велик, и его размер не влезет в число типа int, то получится переполнение, что в свою очередь приведёт к корявым ошибкам.

Разные "православные" способы, как узнать размер файла можно прочитать вот здесь: http://forum.sources.ru/index.php?showtopic=55181

А ещё, размер файла - это априори положительное число. Поэтому, будет более логично юзать unsigned int вместо простого int
А ещё, для этих целей существует даже такой православный тип данных: size_t (тоже самое, что и unsigned int, если не ошибаюсь)

Последний раз редактировалось _Bers; 08.01.2012 в 13:26.
_Bers вне форума Ответить с цитированием
Старый 08.01.2012, 15:07   #7
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию

Эти заморочки важны конешно но у меня файлы по 30 байт пока максимум, мне главное чтобы все остальное работало хорошо, а у меня проблема при записи данных типа char. с интом все нормально.
с интом как записываю два элемента, к нем два интовых указателя - 16 байт памяти. все нормально
с чаром - записываю один элемент - 5 байт, все нормально. 4 на интовый указатель, 1 на чаровский элемент.
записываю два чаровских элемента файл занимает 11 байт!!!, как!?
Вложения
Тип файла: rar FuckingKurs.rar (595.2 Кб, 6 просмотров)
pinkiller вне форума Ответить с цитированием
Старый 08.01.2012, 15:21   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

возможно, тебя подводит вот эта вот вещь: reinterpret_cast<тип>
_Bers вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
нужна одно table где все rows from table 1 но и еще добавленных table 2 Why Помощь студентам 0 20.09.2010 10:29
Установка XP на SATA и все-все-все Alex Cones Операционные системы общие вопросы 5 16.03.2010 17:07
Удалить все потоки при закрытии, предварительно не создавав массив их хендлов? TwiX Общие вопросы Delphi 4 18.02.2010 22:54
Не удаляется файл, не закрыты все потоки для этого файла oirren Общие вопросы по Java, Java SE, Kotlin 1 20.12.2009 21:12