Консультация № 178620
24.05.2010, 23:32
42.16 руб.
25.05.2010, 18:07
0 8 1
Для хранения данных о ноутбуках описать структуру. Написать функцию, которая читает данные о ноутбуках из файла note.txt в структуру приведенного вида. Написать функцию, которая записывает содержимое структуры в конец бинарного файла. Структура бинарного файла: первое два бита (целое) - число записей в файле; далее записи в формате структуры NOTEBOOK.
Написать программу, в которой на основе разработанных функций осуществляется чтение данных только для тех ноутбуков, объем HDD которых меньше 1 Гбайт, и запись считанных данных в бинарный файл в алфавитном порядке по наименованию.
Сам файл note.txt URL >>
самое главное (цитирую слова препода) Представить в виде списка(списков)(а).
сделать в консольном режиме.
то что в файле:
(название)(цена)(масса)(габариты)(частота процессора)(ОЗУ)(диагональ)(видеопамять)(разрешение)(регенерация дисплея)(объем HDD Гбайтах [число с десятичной точкой из пяти символов)
---------------------------------------------------------
структура вида
Код:
struct NOTEBOOK{
char model[21]; //наименование
struct size{ // габаритные размеры
float x;
float y;
float z;
};
float w; //вес
int price; //цена
}

---------------------------------------------------------

P.S Операционная система Windows 7
среда разработки Microsoft Visual Studio 2008
прогу нужно написать на С++
постарайтесь написать попроще. и побольше комментариев.

Обсуждение

Неизвестный
25.05.2010, 17:32
общий
<======================================>

Полностью изменил условие задачи!

Для хранения данных о ноутбуках описать структуру. Написать функцию, которая читает данные о ноутбуках из файла note.txt в структуру приведенного вида. Написать функцию, которая записывает содержимое структуры в конец бинарного файла. Структура бинарного файла: первое два бита (целое) - число записей в файле; далее записи в формате структуры NOTEBOOK.
Написать программу, в которой на основе разработанных функций осуществляется чтение данных только для тех ноутбуков, объем HDD которых меньше 1 Гбайт, и запись считанных данных в бинарный файл в алфавитном порядке по наименованию.
Сам файл note.txt http://reshebniki.my1.ru/note.txt
самое главное (цитирую слова препода) Представить в виде списка(списков)(а).
сделать в консольном режиме.
то что в файле:
(название)(цена)(масса)(габариты)(частота процессора)(ОЗУ)(диагональ)(видеопамять)(разрешение)(регенерация дисплея)(объем HDD Гбайтах [число с десятичной точкой из пяти символов)
---------------------------------------------------------
структура вида
struvt NOTEBOOK{
char model[21]; //наименование
struct size{ // габаритные размеры
float x;
float y;
float z;
};
float w; //вес
int price; //цена
}
---------------------------------------------------------

P.S Операционная система Windows 7
среда разработки Microsoft Visual Studio 2008
прогу нужно написать на С++
постарайтесь написать попроще. и побольше комментариев.
Неизвестный
26.05.2010, 22:44
общий
это ответ
Здравствуйте, Иванов Евгений Витальевич.
Программа. С++. MS VS 2010
Код:
#include <locale>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstring>
#include <iterator>
#include <valarray>
#include <stdexcept>
#include <regex>
#include <cerrno>

#include <list>

// Входной файл
const char* const IN_FILE_NAME="../Data/note.txt";
// Выходной файл
const char* const OUT_FILE_NAME="note.bin";
// Величина табуляции по умолчанию
const size_t TAB_WIDTH=8;

// Типы используемых данных
// Введены для улучшения совместимости и меньшего количества ручной работы
// для написания сходных заданий 178618, 178619, 178620

// Тип символов с которыми будем работать
typedef char CharType;

// Пробел
const CharType SPACE=' ';

// Строковый тип
typedef std::basic_string<CharType> String;
// Файловые типы
typedef std::basic_ifstream<CharType> InFile;
typedef std::basic_ofstream<CharType> OutFile;
// Базовый контейнер
typedef std::list<class Notebook> BaseContainer;

// Габариты
class BoxSize
{
public:
explicit BoxSize(float x=0,float y=0,float z=0);
float x()const;
float y()const;
float z()const;
private:
float _x,_y,_z;
};

// Оператор вывода для BoxSize
template<class Elem,class Traits>
std::basic_ostream<Elem,Traits>& operator<<(std::basic_ostream<Elem,Traits>& stream,const BoxSize& size)
{
const std::ctype<Elem>& fac=std::use_facet<std::ctype<Elem> >(stream.getloc());
Elem x=fac.widen('x');
return stream<<size.x()<<x<<size.y()<<x<<size.z();
}

// Класс - ноутбук
class Notebook
{
public:
// Длина наименования модели
static const size_t MODEL_LEN=20;

Notebook(const char* const model,BoxSize size,float weight,int price);

// Модель
const char* const model()const;
// Габариты
BoxSize size()const;
// Вес
float weight()const;
// Цена
int price()const;
// Метод записывающий данные в конец бинарного файла. true в случае успеха
bool write(OutFile& file)const;
private:
char _model[MODEL_LEN+1];
BoxSize _size;
float _weight;
int _price;

};

// Оператор вывода для Notebook
template<class Elem,class Traits>
std::basic_ostream<Elem,Traits>& operator<<(std::basic_ostream<Elem,Traits>& stream,const Notebook& notebook)
{
return stream<<std::left<<std::setw(Notebook::MODEL_LEN)<<notebook.model()<<'\t'
<<std::setw(6)<<notebook.price()<<'\t'
<<std::setw(5)<<notebook.weight()<<'\t'<<notebook.size();
}

// Класс - контейнер создан для меньшего количества исправлений необходимых для решения 3х задач
// Базовый класс - список
class Container:protected BaseContainer
{
public:
// Заносит запись в контейнер
void put(const Notebook& note);
// Извлекает запись из контейнера
Notebook get();
// Сортирует данные в контейнере используя функцию-предикат
void sort(bool (*pred)(const Notebook&,const Notebook&));

// Откроем для публичного доступа некоторые члены базового класса
BaseContainer::begin;
BaseContainer::end;
BaseContainer::size;
typedef BaseContainer::iterator iterator;
typedef BaseContainer::const_iterator const_iterator;
};

// Функция-предикат для сортировки
bool sortPredicate(const Notebook& n1,const Notebook& n2);

// Ф-я возвращает контейнер с записями о ноутбуках у которых объем HDD<1Gb
Container readHDDLess1Gb(InFile& file);

int main()
{
std::locale::global(std::locale(""));
setlocale(LC_NUMERIC,"C");

try
{
// Откроем файл
InFile inFile(IN_FILE_NAME);
if(!inFile)
{
throw InFile::failure(std::string("Не возможно открыть файл:")+IN_FILE_NAME);
}

// Читаем данные
Container notes=readHDDLess1Gb(inFile);

// Закроем файл
inFile.close();

// Откроем файл для вывода как двоичный
OutFile outFile(OUT_FILE_NAME,OutFile::binary|OutFile::trunc|OutFile::out);
if(!outFile)
{
throw OutFile::failure(std::string("Не возможно открыть файл:")+OUT_FILE_NAME);
}
outFile.exceptions(outFile.failbit);

#ifdef _DEBUG
std::cout<<"Выводим данные о ноутбуках с объемом HDD менее 1Gb"<<std::endl;
#endif
try
{
// Выводим 2 байта информации о количестве записей
unsigned short size=notes.size();
outFile.write(reinterpret_cast<const CharType*>(&size),sizeof(size));
// Выводим в файл и на экран для контроля
for(Container::const_iterator it=notes.begin();it!=notes.end();++it)
{
it->write(outFile);
#ifdef _DEBUG
std::cout<<*it<<std::endl;
#endif
}

outFile.close();
}
catch (OutFile::failure& ex)
{
std::cerr<<"Ошибка записи в файл:"<<OUT_FILE_NAME<<std::endl<<ex.what()<<std::endl;
return 1;
}
}
catch (std::exception& ex)
{
std::cerr<<"Исключение: "<<ex.what()<<std::endl;
}
catch(...)
{
std::cerr<<"Неизвестное исключение"<<std::endl;
}

_getwch();

return 0;
}

bool sortPredicate(const Notebook& n1,const Notebook& n2)
{
return strcoll(n1.model(),n2.model())<0;
}

// Ф-я удаляет символы табуляции из файла
// Поскольку нет точной спецификации на формат входных данных приходится гадать
String expandTabs(const String& str,const size_t tabWidth=TAB_WIDTH)
{
String result;
// Идем по строке
for(String::const_iterator it=str.begin(),end=str.end();it!=end;++it)
{
// Если встретился знак табуляции
if(*it=='\t')
{
// Вычисляем количество необходимых пробелов
String::size_type spaceCount=static_cast<String::size_type>(std::ceil(static_cast<double>(result.length())/tabWidth)*tabWidth)-result.length();
if(!spaceCount)
{
spaceCount=tabWidth;
}
// Заменяем табуляцию пробелами
result+=String().assign(spaceCount,SPACE);
}
else
{
result+=*it;
}
}
return result;
}

// Размер полей данных в файле
const size_t FIELDS_LENGTH[]={24,8,8,16,8,8,8,8,16,8,8};
// Их количество
const size_t FIELDS_COUNT=sizeof(FIELDS_LENGTH)/sizeof(FIELDS_LENGTH[0]);

// Для удобства именуем эти поля
enum FIELD_NAMES
{
MODEL_INDEX=0,
PRICE_INDEX,
WEIGHT_INDEX,
SIZE_INDEX,
HDD_SIZE_INDEX=10
};

// Удаляет начальные/конечные пробелы из строки
String trim(const String& str)
{
String::size_type beg=0,end=str.length();
// Ишем первый не пробел
while(beg<end)
{
if(!isspace(str[beg]))
{
break;
}
++beg;
}
// Ищем последний не пробел
while(beg<end)
{
if(!isspace(str[end-1]))
{
break;
}
--end;
}
return str.substr(beg,end-beg);
}

typedef std::valarray<String> Fields;

// Разбивает строку на набор полей данных. Если удачно то возвращает true
bool parseNoteString(const String& str,Fields& result)
{
result.resize(FIELDS_COUNT);
// Перебираем поля
for(size_t i=0,offset=0;i<FIELDS_COUNT;offset+=FIELDS_LENGTH[i++])
{
// Если смещение в строке меньше ее длины
if(offset<str.length())
{
result[i]=trim(str.substr(offset,FIELDS_LENGTH[i]));
}
else
{
return false;
}
}
return true;
}

// Конвертирует строку в действительное float
float convertToFloat(const String& str)
{
float result=static_cast<float>(atof(str.c_str()));
if(errno==EINVAL)
{
throw std::invalid_argument("float convertToFloat(const stringT& str):Невозможно преобразовать строку в число");
}
return result;
}

// Конвертирует строку в целое int
int convertToInt(const String& str)
{
int result=atoi(str.c_str());
if(errno==EINVAL)
{
throw std::invalid_argument("int convertToInt(const stringT& str):Невозможно преобразовать строку в число");
}
return result;
}

// Конвертирует строку в BoxSize
BoxSize convertToSize(const String& str)
{
// Регулярное выражение для проверки формата данных
static const std::tr1::basic_regex<CharType> rx("(.+)[xX](.+)[xX](.+)");
std::tr1::match_results<String::const_iterator> mr;
if(!std::tr1::regex_search(str,mr,rx))
{
throw std::invalid_argument("noteT::noteSizeT convertToSize(const stringT&): Входные данные имеют не верный формат");
}

return BoxSize(convertToFloat(mr[1].str()),convertToFloat(mr[2].str()),convertToFloat(mr[3].str()));
}

Container readHDDLess1Gb(InFile& file)
{
Container result;
String str;
size_t countStr=0;
std::getline(file,str);
while(file)
{
++countStr;
str=expandTabs(str);
Fields fields;
if(parseNoteString(str,fields))
{
try
{
if(convertToFloat(fields[HDD_SIZE_INDEX])<1)
{
result.put(Notebook(
fields[MODEL_INDEX].c_str(),
convertToSize(fields[SIZE_INDEX]),
convertToFloat(fields[WEIGHT_INDEX]),
convertToInt(fields[PRICE_INDEX])));
}
}
catch(std::invalid_argument&)
{
std::cerr<<"Ошибка во входных данных"<<std::endl;
throw;
}
}
std::getline(file,str);
}
return result;
}

#pragma region BoxSize
BoxSize::BoxSize(float x/*=0*/,float y/*=0*/,float z/*=0*/)
:_x(x)
,_y(y)
,_z(z)
{}

float BoxSize::x() const
{
return _x;
}

float BoxSize::y() const
{
return _y;
}

float BoxSize::z() const
{
return _z;
}
#pragma endregion BoxSize

#pragma region Notebook
Notebook::Notebook(const char* const model,BoxSize size,float weight,int price)
:_size(size)
,_weight(weight)
,_price(price)
{
if(model)
{
strcpy_s(_model,model);
}
else
{
memset(_model,0,MODEL_LEN+1);
}
}

const char* const Notebook::model() const
{
return _model;
}

BoxSize Notebook::size() const
{
return _size;
}

float Notebook::weight() const
{
return _weight;
}

int Notebook::price() const
{
return _price;
}

bool Notebook::write(OutFile& file) const
{
if(file)
{
// Запись в файл
file.write(reinterpret_cast<const CharType*>(this),sizeof(*this));
return !file.fail();
}
else
{
return false;
}
}
#pragma endregion Notebook

#pragma region Container
void Container::put(const Notebook& note)
{
push_back(note);
}

Notebook Container::get()
{
Notebook note=this->front();
pop_front();
return note;
}

void Container::sort(bool (*pred)(const Notebook&,const Notebook&))
{
// STL - списки не поддерживают сортировку. Поэтому реализуем сами подобие пузырьковой
for(iterator it1=begin();it1!=end();++it1)
{
iterator it2=it1;
for(++it2;it2!=end();++it2)
{
if(!pred(*it1,*it2))
{
std::swap(*it1,*it2);
}
}
}
}
#pragma endregion Container

Пример работы:
Код:
Выводим данные о ноутбуках с объемом HDD менее 1Gb
Acer Note Light 2699 5.6 2x11.8x8.3
AST Ascentia P50 4499 7.5 2.3x11.3x9
BSI NP8657D 2605 8 2.3x11.8x9.3
Dell Xpi P100SD 3459 6 2.3x11x8.8
Gateway Solo S5 4499 5.6 2x11.9x8.8
IBM ThinkPad 560 3749 4.1 1.3x11.8x8.8
NEC Versa 4080H 4780 6 2.3x11.8x9.5
Samsung SENS 810 3667 8.7 2.3x11.5x9.5
Twinhead Slimnote 2965 7.4 2x11.5x8


Вот Ваше решение с 3-мя проектами сразу(178618,178619,178620).

[size=2]Прикреплен файл проекта для MS VS 2010.[/size]
-
Прикрепленные файлы:
Неизвестный
26.05.2010, 23:26
общий
Иванов Евгений Витальевич:
Вы вообще STL учили, а то я все через нее сделал?
Неизвестный
26.05.2010, 23:27
общий
отблагодарил на 80р.


при отладке выдает ошибку.
кажется я что то не так запускаю.
заархивируйте проект пожалуйста и отправьте на E-mail ifreeman911@gmail.com
Неизвестный
26.05.2010, 23:28
общий
ifreeman911@gmail.com
Неизвестный
26.05.2010, 23:42
общий
Иванов Евгений Витальевич:
Пишите, что за ошибка, а проект и так прикреплен.
Неизвестный
27.05.2010, 00:02
общий
Программа нужна в MS VS 2008
Неизвестный
31.05.2010, 23:33
общий
Отправил обещанную благодарность.
80р + 40р + 80р

Извините что поздно. (обещал в пятницу) просто реально не было времени.
Форма ответа