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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 31.05.2012, 15:35   #1
Hacker19_90
Delphi Warrior
Старожил
 
Аватар для Hacker19_90
 
Регистрация: 15.08.2008
Сообщений: 2,502
По умолчанию fstream && struct

доброго времени суток!
Возникла проблемка при записи структур в файл
пишу так
Код:
ofstream fout(filename.c_str(), ofstream::binary);
	cout << "count of books?" << endl;
	cin >> count;
	if (fout)
		for(int i = 0; i < count; i++)
		{
			cout << "#" << i+1 << " book:" << endl;
			cout << "name of book: " << endl;
			cin >> book1.name;
			cout << "special of book" << endl;
			cin >> book1.special;
		  fout.write((char*)&book1, sizeof(book));
		  fout.flush();
		}
	fout.close();
читаю так
Код:
ifstream fin(filename.c_str(), ifstream::binary);
	fin.seekg(0, ifstream::beg);
	if (fin)
		while(!fin.eof())
		{	 
       fin.read((char*) &temp, sizeof(book));
		 cout << temp.name << "\t" << temp.special << endl;
		}
	fin.close();
структура
Код:
struct book
{
	char name[21];
	char special[11];
};
Вопрос:
Почему при считывании у меня последняя структура дважды выводится?
Я ошибся где то при вводе или выводе?
Что я не усмотрел?
Всем спасибо!
Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq - 636-954-303
Hacker19_90 вне форума Ответить с цитированием
Старый 01.06.2012, 15:19   #2
Hacker19_90
Delphi Warrior
Старожил
 
Аватар для Hacker19_90
 
Регистрация: 15.08.2008
Сообщений: 2,502
По умолчанию to be continued...

И так! я переписал проект и собствеено выкладываю его вам весь!
вопрос тот же почему не срабатывает eof
Хотя размер файла делёный на размер структуры равен количеству записанных мной структур!
код
Код:
#include <fstream>
#include <iostream>
#include <cstdlib>

using namespace std;

struct somestruct {
	char str[11];
	int i;
};

int main () {
	somestruct ss;
	char fname [] ="somefile.dat";
	ofstream fout(fname, ios::binary);
	cout << "input: " << endl;
	if (fout)
		for (int j = 0; j < 4; j++) {
			cout << "#" << j << endl;
			cin >> ss.str >> ss.i;
			fout.write((char*) &ss, sizeof(somestruct));
		}
	fout.close();
	cout << "end input " << endl;
	system("pause");
	system("cls");
	ifstream fin(fname, ios::binary);
	if (fin)
		while (!fin.eof()) {
			fin.read((char*) &ss, sizeof(somestruct));
			cout << ss.str << "\t" << ss.i << endl;
		}
	fin.close();
	cin.ignore();
	cin.get();
	return 0;
}
вложения
скрины и архив с ехе и исходником
Изображения
Тип файла: jpg input.JPG (12.8 Кб, 65 просмотров)
Тип файла: jpg ouput.JPG (10.4 Кб, 66 просмотров)
Вложения
Тип файла: zip С++.zip (291.3 Кб, 6 просмотров)
Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq - 636-954-303
Hacker19_90 вне форума Ответить с цитированием
Старый 01.06.2012, 22:49   #3
zvoronz
Пользователь
 
Регистрация: 03.01.2011
Сообщений: 49
По умолчанию

Вот в этом месте

Код:
while (!fin.eof()) {
			fin.read((char*) &ss, sizeof(somestruct));
			cout << ss.str << "\t" << ss.i << endl;
		}
Всегда делал вот так
Код:
while (fin.read((char*) &ss, sizeof(somestruct)) && !fin.eof()) {			
			cout << ss.str << "\t" << ss.i << endl;
		}
и всё работало.
zvoronz вне форума Ответить с цитированием
Старый 01.06.2012, 23:29   #4
Hacker19_90
Delphi Warrior
Старожил
 
Аватар для Hacker19_90
 
Регистрация: 15.08.2008
Сообщений: 2,502
По умолчанию

спасибо конечно!
Но более интересно почему именно eof сама по себе не срабатывает?
Просто как это обойти я знаю. Но вот почему dont working? i dont know!
Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq - 636-954-303

Последний раз редактировалось Hacker19_90; 01.06.2012 в 23:34.
Hacker19_90 вне форума Ответить с цитированием
Старый 01.06.2012, 23:36   #5
zvoronz
Пользователь
 
Регистрация: 03.01.2011
Сообщений: 49
По умолчанию

Если с английским дружите

If the End-of-File is reached before n characters have been read, the array will contain all the elements read until it, and the failbit and eofbit will be set (which can be checked with members fail and eof respectively).

То есть пока вы не попытаетесь прочитать дальше конца файла флаг eofbit не будет установлен.
zvoronz вне форума Ответить с цитированием
Старый 01.06.2012, 23:43   #6
Hacker19_90
Delphi Warrior
Старожил
 
Аватар для Hacker19_90
 
Регистрация: 15.08.2008
Сообщений: 2,502
По умолчанию

Господи родной! Да где же вы раньше то были?
+1 ВАМ ОДНОЗНАЧНО!
Теперь то всё понятно!
Получается после прочтения последней записи, eof true не возращает поэтому получается ещё один холостой проход цикла в котором собствено read устанавлиается флаг, ну а так как прочитать уже ничего не можем старая структура и выводится!
ХЕХЕ как всё просто! ЕЩЁ РАЗ СПАСИБО!
Тему можно закрывать!
Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq - 636-954-303
Hacker19_90 вне форума Ответить с цитированием
Старый 02.06.2012, 01:15   #7
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Один момент:

Код:
while (fin.read((char*) &ss, sizeof(somestruct)) && !fin.eof()) {
Булевые операции есть "ленивые". Рассмотрим следующую ситуацию:

if( Foo()==1 && Bar()==1) { /*что то делаем*/ }

Булевое "и" есть истина только и только в том случае, если и Foo()==1 и Bar()==1

Если же Foo() вернёт не_единицу, то условие уже априори false. Не зависимо от того, что вернет второй операнд. А посему, он даже и не будет вычисляться (а зачем делать лишьние движения?)

Теперь представим, что Foo() очень тяжелая функция, а Bar() выполняется почти мгновенно. В этом случае, если переставить в булевом выражении функции местами, то смысл не изменится, а производительность резко вырастит.

В действительности, если легкая Bar() вернёт false, то тяжелая Foo() даже не будет запущена, что сэкономит и время и память.

Итого: есть смысл ставить более легкие процедуры в левой части булевых выражений:

Код:
while (fin.read((char*) &ss, sizeof(somestruct)) && !fin.eof()) {
fin.eof() тупо возвращает флаг.
fin.read() обращается к системе, и задействует тяжелую операцию чтения из файла.

Если поменять их местами - смысл не изменится, но программулька будет меньше жрать памяти и быстрее бегать.
_Bers вне форума Ответить с цитированием
Старый 02.06.2012, 01:58   #8
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

Берс, есть похожая уловка..
этот код будет менее эффективней работать
Код:
for(i=0; i<sizeof(str); i++){
/* do something */
}
чем этот
Код:
t=sizeof(str);
for(i=0; i<t; i++){
/* do something */
}
Спеши медленно.
asmars вне форума Ответить с цитированием
Старый 02.06.2012, 02:01   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от asmars Посмотреть сообщение
Берс, есть похожая уловка..
этот код будет менее эффективней работать
Код:
for(i=0; i<sizeof(str); i++){
/* do something */
}
чем этот
Код:
t=sizeof(str);
for(i=0; i<t; i++){
/* do something */
}
Ты ошибаешься. sizeof вычисляет времени компиляции.
В обоих твоих случаях результат будет одинаковый.
_Bers вне форума Ответить с цитированием
Старый 02.06.2012, 09:59   #10
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

хм..
а если вместо sizeof поставить strlen ?
Спеши медленно.
asmars вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
void to struct (C++) slim>>> Помощь студентам 1 13.01.2011 20:52
Struct, union HeLiO Общие вопросы C/C++ 6 29.12.2010 12:16
Struct mansp Общие вопросы C/C++ 4 05.12.2010 20:00
Вопрос по Struct cheblya Общие вопросы C/C++ 2 06.11.2009 11:42
STRUCT() alexov Общие вопросы C/C++ 1 13.01.2009 18:13