Задача: Текстовые файлы, хранение структурных данных в текстовых файла

  • Автор темы Antonxa
  • Дата начала
A

Antonxa

#1
Входной файл сохраняет следующую информацию по студентам:
<Фамилия>, <имя>, <отчество>, <год рождения>, <курс>, <пол>,
причем фамилия, имя и отчество имеют не более 12 символов, пол - указывается символами М и Ж, год рождения - целое из 4 цифр, курс - целое от 1 до 5. Данные по студентам отделяются знаком «;».
Необходимо написать программу, которая выводит наиболее распространенное мужское и женское имя;

С++
Вот фрагмент программы, который кое-как написал да и тот не работает.
Выручайте.

C++:
#include "conio.h"
#include "iostream"
#include "string.h"
using namespace std;



char surname[13],name[13],otchestvo[13], year[5],course[2], sex[2];
int i,size,j,m=0;
FILE *F;
char str[1000];
int main()
{
F=fopen("laba4.txt","rt");
while(!feof(F))
{fgets(str, 1000, F);
cout<<str;}


while(!feof(F)){
size=strlen(str);
for(i=0;i<size;i++)
{

if(m==0)
{
if(str[i]!=';')

{
surname[j++]=str[i];}
else{m++;
j=0;

continue;
}
}

if(m==1)
{if(str[i]!=';')
{name[j++]=str[i];}
else{m++;
j=0;
continue;}}

if(m==2)
{if(str[i]!=';')
{otchestvo[j++]=str[i];}
else{m++;
j=0;
continue;}}
if(m==3)
{if(str[i]!=';')
{year[j++]=str[i];}
else{m++;
j=0;
continue;}}


if(m==4)
{if(str[i]!=';')
{course[j++]=str[i];}
else{m++;
j=0;
continue;}}

if(m==5)
{if(str[i]!=';')
{sex[j++]=str[i];}
else{m++;
j=0;
continue;}}
}


getch();
return 0;
}
вот файл с которым я работал:

Smirnov;Vladimir;Andreevich;1991;3; M;
Ivanova;Anna;Nikolaevna;1989;4;F;
Kuznetsov;Vladimir;Alekseevich;1992;2 ;M;
Popov;Vladislav;Victorovich;1991;3; M;
Lebedeva;Irina;Igorivna;1993;1;F;
Kozlova;Ekaterina;Antonovna;1989;4; F;
Novikov;Vladimir;Semenovich;1985;5 ;M;
Morozova;Nataliya;Andreevna;1990;5; F;
Petrova;Anna;Sergeevna;1992;2 ;F;
Fedorov;Pavel;Gogavich;1992;2;M;
 

lazybiz

Well-known member
03.11.2010
1 339
0
#2
Я так понимаю, программа должна вывести Vladimir и Anna ?
 
A

Antonxa

#3
Теперь да(немного исправил файл).Но у меня не дописана прога.Да и эта часть тоже не работает.
 
I

ierofant

#4
Каждая запись должна начинаться с новой строки или нет? В задании об этом ничего не сказано.
 
E

ensane

#5
Стандартную библиотеку изучали? Если да - то задача решается быстро и элегантно...
 

DarkKnight

Well-known member
01.08.2010
653
0
#6
C++:
/*
/*
Входной файл сохраняет следующую информацию по студентам:
<Фамилия>, <имя>, <отчество>, <год рождения>, <курс>, <пол>,
причем фамилия, имя и отчество имеют не более 12 символов, пол - указывается символами М и Ж, 
год рождения - целое из 4 цифр, курс - целое от 1 до 5. Данные по студентам отделяются знаком «;».
Необходимо написать программу, которая выводит наиболее распространенное мужское и женское имя;
*/
/*
codeby.net
Autor: DarkKnight125 (Denis Goncharov)
*/
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

//Структура Студент
struct TSTUDENT
{
char	Fam[13]; //Фамилия
char	Name[13]; //Имя 
char	Father[13]; //Отчество
int		god; //Год рождения
int		kurs; //Курс
char	Sex; //Пол
};

int Menu(void)
{
cout << "			МЕНЮ" << endl;
cout << "(1): Ввод данных о студенте" << endl;
cout << "(2): Подгрузка данных из файла" << endl;
cout << "(3): Вывод всех записей" << endl;
cout << "(4): Запись всех данных в файл" << endl;
cout << "(5): Вывод условия задачи (наиболее встеч. имя)" << endl;
cout << "(6): Выход" << endl;
int Selection = 7;
cout << "Сделайте выбор : ";
while (Selection > 6)
{
cin >> Selection;
}
return Selection;
}

//Функция ввода данных о студенте
void InputStudent (TSTUDENT* Arr,int Position)
{
TSTUDENT Temp;
Temp.kurs = 6;
Temp.Sex = '\0';
char buffer[1024]={0};
memset(&Temp,0,sizeof(TSTUDENT));
cin.sync(); //Синхронизируем поток ввода
cout << "Введите фамилию студента : ";
cin.getline(buffer,1023);
strncpy(Temp.Fam,buffer,12);
cout << "Введите имя студента : ";
cin.getline(buffer,1023);
strncpy(Temp.Name,buffer,12);
cout << "Введите Отчество студента : ";
cin.getline(buffer,1023);
strncpy(Temp.Father,buffer,12);
cout << "Введите год рождения студента: ";	
cin >> Temp.god;
cout << "Введите курс студента : ";	
while (Temp.kurs < 1 || Temp.kurs > 5)
cin >>Temp.kurs;
cout << "Введите пол студента (m/f) : ";
while (Temp.Sex != 'm' && Temp.Sex != 'f')
cin>> Temp.Sex;
Arr[Position] = Temp;
}

//Вывод записи на экран
void PrintInfo (TSTUDENT* Arr, int Position)
{
cout << setw(13) << Arr[Position].Fam << setw(13) << Arr[Position].Name << setw(13) << Arr[Position].Father << setw(5) << Arr[Position].god << setw(5) << Arr[Position].kurs << setw(4) << Arr[Position].Sex << endl;
}

//Основная функция (точка входа)
void main(void)
{
setlocale(LC_ALL,".1251"); //Установим локаль в 1251-код. страницу
TSTUDENT Arr[500]; //Массив данных о студентах (макс. 500 студентов)
unsigned int CountStudent = 0; //Размерность массива студентов
ifstream FileIn; //Файловый поток (входной)
ofstream FileOut; //Файловый поток (выходной)
char FileNameOut[128]={0}; //Имя файла для вывода информации
int UserSelection = 0;

cout.setf(ios_base::left);

while (UserSelection != 6)
{
UserSelection = Menu();
switch (UserSelection)
{
case 1:
InputStudent(Arr,CountStudent);
CountStudent++;
break;
case 2:
break;
case 3:
cout <<setw(39)<<"Ф.И.О."<<setw(5)<<"г.р." << setw(5) << "Курс" << setw(4) << "Пол" << endl;
for (int i = 0; i < CountStudent; i++)
PrintInfo(Arr,i);
break;
case 4: 
cin.sync(); //Синхронизорование стандартного потока ввода
cout<< "Введите имя файла: ";
cin.getline(FileNameOut,127);

FileOut.open(FileNameOut); //Открытие файла вывода

if (!FileOut)
{
cout << "Ошибка : Создания файла вывода информации" << endl;
return;
}

for (int i = 0; i< CountStudent; i++)
{
FileOut << Arr[i].Fam << " "<< Arr[i].Name << " " << Arr[i].Father << " " << Arr[i].god <<" " << Arr[i].kurs << " " << Arr[i].Sex << ";";
}
FileOut.close(); //Закрытие файла вывода
break;
case 5:
break;
default:
break;
}
}

}
2 Antonxa: Допишу уже завтра, голова болит ужастно....


Стандартную библиотеку изучали? Если да - то задача решается быстро и элегантно...
Быстроты и элегантности в решении я не вижу... Такие задачи, я всегда отношу к типу "проект" из-за их объемности кода....
 
R

Rififi

#7
Antonxa

Сегодня утром мне сделали потрясающий кофе, поэтому я стал мега-добрым(((((:)
Вот это - твоё освобождение от зачётов:

C++:
/*
Входной файл сохраняет следующую информацию по студентам:
<Фамилия>, <имя>, <отчество>, <год рождения>, <курс>, <пол>,
причем фамилия, имя и отчество имеют не более 12 символов, пол - указывается символами M и F, 
год рождения - целое из 4 цифр, курс - целое от 1 до 5. Данные по студентам отделяются знаком «;».
Необходимо написать программу, которая выводит наиболее распространенное мужское и женское имя;
*/

#include <map>

#include <boost/spirit/home/qi.hpp>
#include <boost/spirit/home/phoenix.hpp>

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>

namespace qi = boost::spirit::qi;
namespace ex = boost::spirit::iso8859_1;
namespace phx = boost::phoenix;

#include <boost/fusion/adapted.hpp>

struct Person
{
std::string lastName_;
std::string name_;	
std::string surName_;
size_t yearOfBirth_;
size_t course_;
char sex_;
};

BOOST_FUSION_ADAPT_STRUCT(
Person,	
(std::string, lastName_)
(std::string, name_)
(std::string, surName_)
(size_t, yearOfBirth_)
(size_t, course_)
(char, sex_)
)

typedef std::vector<Person> Persons;

#define ConstrainStringLength(len) (qi::_pass = phx::size(qi::_1) <= len)
#define ConstrainRange(l,h) (qi::_pass = (qi::_1 >= l) && (qi::_1 < h))

template <typename InputIterator>
struct grammar : public qi::grammar<InputIterator, Persons()>
{
grammar() : grammar::base_type(start)
{
start = +person;
person =
lastName >> ';' >> name >> ';' >> surName >> ';' >>
yearOfBirth >> ';' >> course >> ';' >> sex >> ';' >> qi::eol;

string = +(ex::char_ - ';');

name %= string.copy() [ ConstrainStringLength(12u) ];
lastName %= string.copy() [ ConstrainStringLength(12u) ];
surName %= string.copy() [ ConstrainStringLength(12u) ];

yearOfBirth %= qi::uint_[ ConstrainRange(1000u, 10000u) ];
course %= qi::uint_ [ ConstrainRange(1u, 6u) ];
sex %= ex::char_("mfMF")[qi::_val = phx::bind(&std::toupper, qi::_1)];
}

qi::rule<InputIterator, Persons()> start;
qi::rule<InputIterator, Person()> person;
qi::rule<InputIterator, std::string()> string, name, lastName, surName;
qi::rule<InputIterator, size_t()> yearOfBirth, course;
qi::rule<InputIterator, char()> sex;
};

void print_name_for(const Persons& p, char sex)
{
std::map<std::string, size_t> m;

using phx::if_;
using phx::arg_names::arg1;
using namespace boost::adaptors;

boost::for_each(p, if_(&arg1 ->* &Person::sex_ == sex)[++phx::ref(m)[&arg1 ->* &Person::name_]]);
std::cout << sex << " => " << boost::max_element(m | map_values).base()->first << std::endl;
}

template <typename Range>
void parse_persons(const Range& rng)
{
Persons persons;

try
{
typedef typename boost::range_iterator<const Range>::type InputIterator;

InputIterator begin = boost::const_begin(rng);
const InputIterator end = boost::const_end(rng);

const grammar<InputIterator> g;
const bool ok = qi::parse(begin, end, g, persons);
if (!(ok && begin == end))
throw std::runtime_error("Parsing failed.");

print_name_for(persons, 'M');
print_name_for(persons, 'F');
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}

int main()
{
const std::string s = 
"Smirnov;Vladimir;Andreevich;1991;3;m;\n"
"Ivanova;Anna;Nikolaevna;1989;4;F;\n"
"Kuznetsov;Vladimir;Alekseevich;1992;2;M;\n"
"Popov;Vladislav;Victorovich;1991;3;M;\n"
"Lebedeva;Irina;Igorivna;1993;1;F;\n"
"Kozlova;Ekaterina;Antonovna;1989;4;F;\n"
"Novikov;Vladimir;Semenovich;1985;5;M;\n"
"Morozova;Nataliya;Andreevna;1990;5;F;\n"
"Petrova;Anna;Sergeevna;1992;2;F;\n"
"Fedorov;Pavel;Gogavich;1992;2;M;\n"		
;

parse_persons(s);

return 0;
}
Вывод программы:

M => Vladimir
F => Anna
 
X

xparen

#8
Очень как-то слишком круто написано.. (2-е решение - Пост выше).
А может кто поможет к коду DarkKnight125 внести дополнение чтобы программа выводила фамилии на заданную нами букву?!
 
R

Rififi

#9
xparen

Очень как-то слишком круто написано.. (2-е решение - Пост выше).

Ну дык. Освобождение от зачётов - это не в носу поковыряться (:) Препода нужно удивить, а еще лучше - шокировать!
 
X

xparen

#10
Ну так помогите плз с моим условием (вывод фамилии по выбранной букве) оч гарю с автоматом по программированию.... только если можно по проще код ... вот одна лаба тупая осталась. Плз (((((((