Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
zyabr
0 / 0 / 0
Регистрация: 25.05.2009
Сообщений: 7
1

Работа с файлами

26.05.2009, 12:01. Просмотров 1445. Ответов 11
Метки нет (Все метки)

Помогите с программкой,пожалуйста.С файлами на С++ никогда не работала, поэтому пришлось в быстрых темпах осваивать самой.
Задание:Программа «Экзаменационный билет»
Экзаменационный билет состоит из двух вопросов (первого и второго). У преподавателя имеется два текстовых файла со списками вопросов (формат которых необходимо продумать).
Программа вызывается каждый раз для очередного студента и должна:
-запросить его фамилию;
-случайным образом выбрать варианты первого и второго вопросов из двух файлов, причем те, что до этого не использовались. В общем случае номера вариантов первого и второго вопросов не должны совпадать, т.е. они выбираются отдельно друг от друга;
-вывести фамилию студента, первый и второй вопросы на экран и принтер;
-сохранить для преподавателя информацию об использованных вопросах в текстовом файле в формате:
Фамилия Номер_первого_вопроса Номер_второго_вопроса
Этот файл должен дополняться после каждого вызова программы завершиться.
Для начала решила сделать что-то пробное.Получилось следующее:

#include <fstream.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
void main()
{int q1[50],q2[50],N;
cout<<"Number of students: ";
cin>>N;
char name[40];
ifstream fin1("list1.txt");
ifstream fin2("list2.txt");
ofstream fout("result.txt",ios::app);
randomize();
for(int k=0;k<N;k++)
{cout<<"Name: ";
cin>>name;
q1[k]=random(22)+1;
q2[k]=random(16)+1;
fout<<name<<' ';
fout<<q1[k]<<' ';
fout<<q2[k]<<'\n';}
fin1.close();
fin2.close();
fout.close();
return;
}

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

Добавлено через 20 часов 12 минут 41 секунду
подскажите, пожалуйста, хоть какие-нибудь команды для работы с файлами...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.05.2009, 12:01
Ответы с готовыми решениями:

Работа с файлами c++
Ребят помогите оч нужно:p Я хочу создать программу чтоб при запуске ее...

Работа с файлами С++
Доброго время суток! Подскажите где создавать текстовый файл для привязки его...

Работа с файлами!!!
помогите решить этот бред, а то с инста попрут 1)описать функцию triangle,...

Работа с файлами
Как нужно сделать при старте программы происходит загрузка списка из указанного...

Работа с файлами C++
Условие: Скопировать из файла F1 в файл F2 все строки, в которых содержится два...

11
Deiron
26 / 26 / 9
Регистрация: 25.05.2009
Сообщений: 98
26.05.2009, 13:19 2
Предлагаю вам следующий вариант. Сделайте вопросы такой структурой:
C++
1
2
3
4
5
struct question
{
 int number;
 char text;
};
напишите маленькую отдельную програмку для занесения этих вопросов в файл
что-нибудь вроде:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
char ans;
question temp;
ofstream f1("questions.txt");
int num=1;
temp.text=new char [100];
do
{
cout<<"введите текст вопроса"<<endl;
cin.getline(temp.text);
temp.number=num;
num++;
f1<<temp;
cout<<"Продолжить ввод вопросов? Y/N"<<endl;
ans=getch();
ans=tolower(ans);
}while (ans=='y');
delete [] temp.text;
С учетом вопросов все проще. Делаете 2 списка (надеюсь, вы знаете, что это такое?), в который загружаете вопросы при чтении из файлов. Поcле того, как вопрос бы выбран, вы его просто удаляете из списка. Выбор элемента списка будет идти после того, как random выдаст вам его номер (после выбора и удаления элемента из списка не забудьте уменьшить число в скобках random на 1)
Не совсем понял данный пункт:
В общем случае номера вариантов первого и второго вопросов не должны совпадать, т.е. они выбираются отдельно друг от друга
То есть, если я выбрал случайным образом из первого списка вопрос с вариантом n, из второго списка я вопрос с таким же номером выбрать не могу?(Запустив генератор случайных чисел второй раз) А в чем смысл? Если вопросы в списках разные? А если одинаковые, то зачем два файла?
0
zyabr
0 / 0 / 0
Регистрация: 25.05.2009
Сообщений: 7
26.05.2009, 14:19  [ТС] 3
Cмысл в том что в общем случае вопросы из первого и второго списка выбираются независимо друг от друга.Но вариант когда они совпали не исключен.
Спасибо большое за помощь!Вот только список вопросов у меня по идеи уже есть.

У преподавателя имеется два текстовых файла со списками вопросов (формат которых необходимо продумать).

Т.е. заново вводить их не нужно.
0
Deiron
26 / 26 / 9
Регистрация: 25.05.2009
Сообщений: 98
26.05.2009, 15:27 4
Наверно я не правильно понял данную фразу
Цитата Сообщение от zyabr Посмотреть сообщение
У преподавателя имеется два текстовых файла со списками вопросов (формат которых необходимо продумать).
Я воспринял это как то, что можно самому выбирать, как именно будут выглядеть эти вопросы. (В смысле, "как хочу, так и храню")
Но даже если эти два списка вопросов уже есть в виде текстовых файлов, где уже известно в каком виде они хранятся, то можно на этапе чтения из файла формировать списки содержащие текст и номер варианта. После рандомизации смотреть на поля, отвечающие за вариант, и, если они одинаковые, то рандомить для второго списка до тех пор, пока у второго не будет отличаться.
Если возникнут проблемы - пиши (только ты сначала лучше сама попробуй со всем этим делом разобраться)
0
zyabr
0 / 0 / 0
Регистрация: 25.05.2009
Сообщений: 7
26.05.2009, 15:30  [ТС] 5
Формат текстового файла нужно продумать, а вот то что он текстовый с готовыми вопросами - это не обсуждается.
простите, конечно, но нельзя ли поподробнее и желательно в коде?
0
Deiron
26 / 26 / 9
Регистрация: 25.05.2009
Сообщений: 98
26.05.2009, 18:03 6
Пожалуйста.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 class Node
{
public:
Node ();
Node(char* data,int v);
Node (char* data,int v, Node* pr);
~Node();
Node* insert(char* data, int v);
friend void create(Node& t,ifstream& base);
private:
char* text; 
int num_var;
Node *prev; 
Node *next;
}
Node::Node()
{
 text=NULL:
 next=NULL;
 prev=NULL;
}
Node::Node(char* data,int v)
{
 Node();
 int size= strlen (data);
 text=new char [size+1];
 strcpy(text,data);
 num_var=v;
}
Node::Node(char* data,int v, Node* pr)
{
 Node(data,v);
 prev=pr;
}
Node::~Node()
{
    delete [] text;
}
Node* Node::insert(char * data,int v)
{
 if (next!=NULL) {next=next->insert(data,v);}
 Node temp=new Node (data,v,this);
 return temp;
}
Это - сам список.
Файл обязательно текстовый? Это несколько усложняет дело. С бинарным файлом было бы работать проще (туда можно было бы записать сам класс). Так же не ясно, даны ли в этом файле и номер варианта и текст вопроса. Вообще не ясно, каково содержимое этого файла.
Вот участок кода для заполнения списка
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void create(Node& t,ifstream& base)
{
 char* st;
 int a_var,first=1;
 //здесь должен быть участок, отвечающий за получение данных из файла.
// участок, следующий ниже, должен производиться в цикле, считывающим файл
 if (first){
  t.text=new char[size];
  strcpy(t.text,st);
  t.num_var=a_var;
  first=0;
 } else {
     t.next=t.next->insert(st,a_var);
 }
}
1
zyabr
0 / 0 / 0
Регистрация: 25.05.2009
Сообщений: 7
27.05.2009, 04:27  [ТС] 7
Вид файла примерно таков:

1. Микропроцессорная система. Состав и характеристики. Микропроцессоры Intel x86. Реальный и защищенный режимы работы. Адресация и сегментация памяти. Механизм прерываний.
2. Построение программ. Интерпретация, компиляция, ассемблирование. Основные этапы построения программы.
3. Языки высокого уровня. Алфавит языка С++. Идентификаторы, константы, знаки операций, разделители.
0
zyabr
0 / 0 / 0
Регистрация: 25.05.2009
Сообщений: 7
27.05.2009, 21:07  [ТС] 8
Решила разобраться сама!Даже что-то получилось. Правда не совсем то что нужно. Помогите прочитать конкретные вопросы из конкретного файла и с random-ом без повторений.А то в 3 часа утра голова не очень варит...
0
Вложения
Тип файла: txt kr.txt (1.4 Кб, 14 просмотров)
Deiron
26 / 26 / 9
Регистрация: 25.05.2009
Сообщений: 98
28.05.2009, 03:54 9
Начнем с простого. random без повторения делается примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 int a;
 //int num_q1,num_q2 - номера вопросов.
 //l1, l2 - списки вопросов из первого и второго файлов с номерами варианта и 
 //текстом вопроса
 randomize();//не нужно, если где-то в программе уже запускался.
 a=random(количество оставшихся неиспользованными вопросов)+1; 
 num_q1=l1.getquestnum(a);//взять номер вопроса а-того билета и поместить его в 
                                      //num_q1
 a=random(количество оставшихся неиспользованными вопросов)+1;
 num_q2=l2.getquestnum(a);
 while (num_q2==num_q1){
      a=random(количество оставшихся неиспользованными вопросов)+1;
      num_q2=l2.getquestnum(a);
 }
 l1.delete(num_q1);//удаляем использованые вопросы из списков вопросов
 l2.delete(num_q2);
// уменьшаем количество неиспользованных вопросов на 1
Почему так? Ну, потому что без удаления вопросов из списка вы потом намучаетесь с учетом использованых вопросов (ведь нужно выбирать вопросы только из тех, что ранее не использовались). Почему значение варианта а-того билета а не само а? Думаю, вы это поймете, если представите себе ситуацию, когда из 20 билетов остается, скажем, 5, и вы берете из них, допустим, 3й слева.

Чтение из файла:
делается цикл while(!(f.eof())){действия}
вам могут пригодится следующие ф-ции:
istream& get(куда,сколько символов,символ ограничения); для вопроса формата 1. текст этот симовл - '.' а для самого текста - тут уж определитесь сами. (если текст вопроса занимает несколько строк, то при установке символа ограничения '\0' могут возникнуть проблемы). Можете так же посмотреть про getline
istream& ignore (2,EOF); - удалить 2 символа из входного потока (мы "взяли" номер варианта, но точка и пробел остались. Вот их то мы и пропускаем). Попробуете написать функцию чтения из файла самостоятельно?
Далее, по поводу вашего кода:
C++
1
2
3
4
5
6
7
8
9
10
11
QUES* head=0;//разве компилятор не будет ругаться на не статическую //переменную, объявленную вне main-а? И вместо 0 лучше все же написать NULL
void add(QUES* LC)//LC - адрес нового элемента списка, который 
{   LC->next=0;
   if(head==0)
      { head=LC;
        return;
      }
   QUES* cur=head;
   while(cur->next) cur=cur->next;
   cur->next=LC;
}
В принципе, данный код верен, но:
1. у вас класс используется фактически как структура. Смысл? Если класс не нужен, объявляйте как struct.
2. Если это класс, то зачем делать add внешним?
3. Зачем делать один список, если проще сделать 3 и один класс-контейнер, который этими 3 списками будет управлять?
(2 списка на вопросы из первого и второго файла, один, в котором вы будете хранить информацию по билетам (очень близко к тому, что сейчас есть у вас в ques))
4. Дополнительная претензия к функции display (ну люблю я придираться, что с меня возьмешь?):
C++
1
2
3
4
5
void QUES:: display()
{
      cout<<name<<" "<<ques1<<" "<<ques2<<"\n";
      if (next) {next->display();}
}
Если написать ее так, объявив ее внутри класса QUES, то она выведет весь список без всяких мучений. Метод класса вызывается точно так же, как производится доступ к полю класса. (l1.show())

Чтобы разобраться со списками рекомендую вам поискать в сети книгу Джесса Либерти "Освой C++ самостоятельно за 21 день." Там все очень хорошо описано в главе "День 13. Массивы и связанные списки", да и вообще, если ваша дальнейшая судьба хоть как то связана с панорамированием, то эта книга может быть для вас весьма и весьма полезной
1
zyabr
0 / 0 / 0
Регистрация: 25.05.2009
Сообщений: 7
28.05.2009, 16:35  [ТС] 10
буду исправлять)

Добавлено через 12 часов 34 минуты 5 секунд
У меня есть код.Но он выводит только номер, а не сам вопрос. Куда и как нужно дописать, чтобы на экран выводилось Имя, №1вопроса, №2вопроса?
Код
#include <stdio.h>
#include <fstream.h>
#include <stdlib.h>
#include <conio.h>
	
class Student
{     private:
              char name;
              int n;  // количество вопросов
      public:
             Student(char a, unsigned b )   //конструктор
                 {name=a; n=b;};
             int Choosevopros1()// выбирает первый вопрос
              {int M[100];
               int i=0;
               char s[40];
               fstream Tempvopros1;
               Tempvopros1.open("temp1.txt",ios::in);
               if(Tempvopros1)
             		while(Tempvopros1.getline(s,sizeof(s)))
                  	{M[i]=atoi(s); i++;}
               Tempvopros1.close();
              		int *h;
                  int n1;
                  int p=1;
                  while(p!=0)
                  	{p=0;
                     n1=1+rand()%n;
                     h=M;
                     	while(*h)
                        {if(n1==*h)
                        {p=1;break;}
                        h++;}
               		Tempvopros1.close(); }
               Tempvopros1.open("temp1.txt",ios::app);
               Tempvopros1<<n1<<"\n";
               Tempvopros1.close();
               return n1;}
             int Choosevopros2()//выбирает второй вопрос
              {int M[100];
              int i=0;
              char s[40];
              fstream Tempvopros2;
              Tempvopros2.open("temp2.txt",ios::in);
              if(Tempvopros2)
              		while(Tempvopros2.getline(s,sizeof(s)))
                  	{M[i]=atoi(s); i++;}
              Tempvopros2.close();
              		int *h;
                  int n2;
                  int p=1;
                  while(p!=0)
                  	{p=0;
                     n2=11+rand()%n;
                     h=M;
                     	while(*h)
                        {if(n2==*h)
                        {p=1;break;}
                        h++;}
              			Tempvopros2.close();}
              Tempvopros2.open("temp2.txt",ios::app);
              Tempvopros2<<n2<<"\n";
              Tempvopros2.close();
              return n2;}
};
/* выводит на принтер и экран */
void Copyvopros(char *name,int nv1, int nv2 )
	 {ifstream outfile("print.txt",ios::in);
               char str[1000];
               cout<<nv1<<"\t"<<nv2<<"\n";
                 if (!outfile.getline(str,sizeof(str)))
                   {ofstream outfile("print.txt",ios::trunc);
                   outfile<<"Фамилия\t\t"<<"Номер_первого_вопроса\t\t"<<"Номер_второго_вопроса"<<"\n";
                   outfile<<"\n"<<name<<"\t\t"<<nv1<<"\t\t\t\t"<<nv2<<"\n";}
                 else
                   {ofstream outfile("print.txt",ios::app);
                   outfile<<"\n"<<name<<"\t\t"<<nv1<<"\t\t\t\t"<<nv2<<"\n";}
                   outfile.close();}
/* записывает отчет в файл */
void Writereport(char *name,int nv1, int nv2 )
                 {ifstream outfile("report.txt",ios::in);
                char st[1000];
                 if (!outfile.getline(st,sizeof(st)))
                  {ofstream outfile("report.txt",ios::trunc);
                  outfile<<"Фамилия\t\t"<<"Номер_первого_вопроса\t\t"<<"Номер_второго_вопроса"<<"\n";
                  outfile<<"\n"<<name<<"\t\t\t"<<nv1<<"\t\t\t\t"<<nv2<<"\n";}
                 else
                  {ofstream outfile("report.txt",ios::app);
                  outfile<<"\n"<<name<<"\t\t\t"<<nv1<<"\t\t\t\t"<<nv2<<"\n";}
                  outfile.close();}
/*--------------------------------*/
main()
     {srand(time(0));
      ifstream inFile1("list1.txt",ios::in);
      if (!inFile1 )
      {cout<<"Error! File 'list1.txt' is not found\nPress any key to exit..";
       getch();
       return 0;}
      ifstream inFile2("list2.txt",ios::in);
      if (!inFile2 )
      {cout<<"Error! File 'list2.txt' is not found\nPress any key to exit..";
       getch();
       return 0;}
       
      char k[3];
      int n;
      ifstream TempFile("temp.txt",ios::in);
      if(!TempFile)
        {cout<<"Welcome to examination ticket programm\nPlease enter how much questions\n";
         cin>>k;
         n=atoi(k);
         ofstream TempFile("temp.txt",ios::app);
         TempFile<<n<<"\n";}
      else
         {TempFile.getline(k,sizeof(k));
          n=atoi(k);}
      TempFile.close();

      char name1[50];
      cout<<"Enter last name student\n";
      cin>>name1;
      Student ST(*name1,n);

      ifstream Tempvopros1("temp1.txt",ios::in);
      char s[5];
      int test=0;
      while(Tempvopros1.getline(s,sizeof(s)))
           {test++;}
      if(test==n)
        {cout<<"All tickets are used\nPress any key to exit...";
              remove("temp.txt");
              remove("temp1.txt");
              remove("temp2.txt");
         getch();
         return 0;
        }
      int nv1=ST.Choosevopros1();
      int nv2=ST.Choosevopros2();
      Writereport(name1,nv1,nv2);
      cout<<"\nLast name-"<<name1<<"\t\n\n";
      Copyvopros(name1,nv1,nv2);
         ofstream printfile("print.txt",ios::app);
         printfile.close();
      cout<<"\n"<<"Press any key to exit..." ;
      getch();
}
0
Deiron
26 / 26 / 9
Регистрация: 25.05.2009
Сообщений: 98
28.05.2009, 18:44 11
Ну, тут все очевидно. Это должно быть в вашей функции Copyvopros/Writereport (насколько я понял, именно она отвечает за вывод в файл и на экран). Там у вас строчка
C++
1
/*куда*/<<"\n"<<name<<"\t\t\t"<<nv1<<"\t\t\t\t"<<nv2<<"\n";
Которая, естественно, выводит имя, номер вопроса 1 и номер вопроса 2. Вывода самих вопросов там нет. Соответственно, чтобы выводился еще и текст вопроса, надо изменять именно эту строку. То есть, условно говоря она должна выглядеть примерно так:
C++
1
/*...*/<<nv1<<"\t\t\t\t"<<quest1_text<<"\t\t\t\t"<<nv2<<"\t\t\t\t"<<quest2_text<<endl;
Примечание: <<endl значит то же, что и <<'\n'

Несколько дополнительных замечаний на будущее:
1. Тела таких функций, как Choosevopros не слишком хорошо оставлять в объявлении класса.
Правильнее будет так:
C++
1
2
3
4
5
6
7
8
9
10
Class ИмяКласса
{
//...
 тип возвращаемого аргумента fun1();
//...
};
тип возвращаемого аргумента ИмяКласса:: fun1()
{
тело функции
}
2. Постарайтесь избавится от названий, содержащих одновременно русские и английские слова (Choosevopros). Это считается дурным тоном в программировании.
3. При названии функций старайтесь следовать "верблюжей нотации" (ChooseQuestion или chooseQuestion) или просто разделяйте слова символом _
1
zyabr
0 / 0 / 0
Регистрация: 25.05.2009
Сообщений: 7
28.05.2009, 18:49  [ТС] 12
Честно говоря код не мой.Вот сижу корректирую, потому как даже на мой взгляд он выглядит коряво.
0
28.05.2009, 18:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.05.2009, 18:49

Работа с файлами.
Имеется файл txt с текстом. Как узнать номер строки в которой только одно...

Работа с файлами в С++
Доброго времени суток! Готовлюсь к зачёту завтра. Там будет задача подобная...

Работа с файлами
Надо считать файл txt произвести вычисления и записать результат в новый файл....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru