Поиск:

Ответ в темуСоздание новой темы Создание опроса
> тест, Please, помогите исправить ошибку 
:(
    Опции темы
veselchak
  Дата 23.8.2006, 07:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.8.2006
Где: Иркутск

Репутация: нет
Всего: нет



Здравствуйте!Вот сделал прогу,преставляющую собой обыкновенный тест. Вроде все правильно, но во время работы эгзешника возникает исключение:"Access violation addres...in module rtl.bpl.Read of addres ...".Ниже исходный текст проги

НА 237 СТРОКЕ В ТЕКСТЕ И ТОРМОЗИЛа ПРОГА(if (dl!=0 ) st->printf("%s",buf);
),НО ИСПРАВИВ ЛЯПУС(if (dl!=0 ) printf("%s",buf);) ПО СОВЕТУ 
ROCKIE ВОЗНИКЛА ТА ЖЕ ОШИБКА,ТОЛЬКО НА 180 СТРОКЕ


Код

//H-файл
#ifndef test1H
#define test1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
struct TVopros
{
AnsiString Vopr; //вопрос

AnsiString Otv[4];//варианты ответа
int nOtv;  //к-во вариантов ответа
int rOtv;  //номер правильного ответа

};


class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TLabel *Label1; //message,вопрос
        TButton *Button1; //кнопка ОК/Дальше
        void __fastcall FormActivate(TObject *Sender);
        void __fastcall Button1Click(TObject *Sender); //Ok,next
private:    // User declarations
//варианты ответа-радиокнопки выбора
TRadioButton *RadioButton[4];
 //щелчок на кнопке выбора правильного ответа
void __fastcall RadioButtonClick(TObject *Sender);
void __fastcall ShowVopros (TVopros v); //write answer
void __fastcall EraseVopros(void);//delete answer

public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

**************************
//текст модуля
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>//доступ к функции sscanf
#include "test1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//int i;
int f;//дескриптор файла теста
int level[4];//к-во правильных ответов,необходимых для достижения уровня
AnsiString mes[4]; //сообщение о достижениии уровня
TVopros Vopros; //вопрос
int otv; //номер выбранного ответа
int right=0; //к-во правильных ответов;
 int i;
 int dl;
//функции,обеспечивающие чтение вопроса из файла теста
 int GetInt(int f); //read entire/byte
int GetString (int f,AnsiString *st); //read string
//---------------------------------------------------------------------------
 //constructor
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
//int i;
int left=10;
for (i=0;i<4;i++)
{
//создадим радиокнопки для выбора прав. ответа
RadioButton[i]=new TRadioButton(Form1) ;
//checked свойства
RadioButton[i]->Parent=Form1;
RadioButton[i]->Left=left;
RadioButton[i]->Width=Form1->ClientWidth - Left - 20;
RadioButton[i]->Visible=false;
RadioButton[i]->Checked=false;
//зададим функцию обработки события клик
RadioButton[i]->OnClick=RadioButtonClick;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
AnsiString st;
//int i;
f=FileOpen("1.txt",fmOpenRead); //open file
if ( f==-1 ) //если файл несуществует
{
Label1->Font->Style=TFontStyles()<<fsBold;
Label1->Caption="Ошибка доступа к файлу 1.txt";
Button1->Tag=2;
return;
}
GetString(f,&st);//прочитать название теста
Form1->Caption=st;
GetString(f,&st);//прочитать вводную информацию
Label1->Width=Form1->ClientWidth -Label1->Left-20;
Label1->Caption=st;
Label1->AutoSize=true;
//прочитать информацию об уровнях оценки
for(int i=0;i<4;i++);
{
level[i]=GetInt(f);
GetString(f,&mes[i]);
}
}
//читает из файла очередной вопрос
bool GetVopros(TVopros *v)
{
AnsiString st;
if (GetString(f,&(v->Vopr)) !=0)
{
//прочитать к-во вариантов ответа и номер правильного ответа
v->nOtv=GetInt(f) ;
v->rOtv=GetInt(f);
for(int i=0;i<v->nOtv;i++); //читаем варианты ответа
{
 GetString (f,&(v->Otv[i]));
}
return true;
}
else return false;
}
//выводит вопрос
void __fastcall TForm1::ShowVopros(TVopros v)
{
int top;
//int i;
Label1->Width=ClientWidth - Label1->Left -20;
Label1->Caption=v.Vopr;
Label1->AutoSize=true;
//variants
for (i=0;i<v.nOtv;i++)
{
RadioButton[i]->Top=top;
RadioButton[i]->Caption=v.Otv[i];
RadioButton[i]->Visible=true;
RadioButton[i]->Checked=false;
top+=20;
}
}
//щелчок на радиокнопке выбора ответа
void __fastcall TForm1::RadioButtonClick(TObject *Sender)
{
int i=0;
while (! RadioButton[i]->Checked)
i++;
otv=i+1;
//ответ выбран,сделаем доступной кнопку  "Дальше"
Button1->Enabled=true;
}
//удаляет вопрос с экрана
void __fastcall TForm1::EraseVopros(void)
{
//скрыть поля выбора ответа
for (int i=0;i<4;i++)
{
RadioButton[i]->Visible=false;
RadioButton[i]->Checked=false;
}
//not enables button next
Button1->Enabled=false;
}
//---------------------------------------------------------------------------
 //щелчок на кнопке Ок/Дальше/Ок
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 bool ok;//результат чтения из файла очередного вопроса
switch (Button1->Tag)
{
case 0: //клик на кнопке ОК в начале работы проги,прочитать и вывести первый вопрос
GetVopros(&Vopros);
        ShowVopros(Vopros);
        Button1->Caption=" Дальше ";
        Button1->Enabled=false;
        Button1->Tag=1;
        break;
case 1:  //clic на кнопке Даьше
if(otv==Vopros.rOtv)//выбран правильный ответ
right++;
EraseVopros();
ok=GetVopros(&Vopros);
if(ok)
 ShowVopros(Vopros);
 else //вопросов нет
 {
 FileClose(f);
 //вывести результата
AnsiString st;
int i; //number достигнутого уровня
Form1->Caption="результат тестирования";
st.printf("Правильных ответов:%i \ n",right);
//определим оценку
i=0;
while ((right<level[i])&(i<3))
i++;
st=st+mes[i];
Label1->Caption=st;
Button1->Caption="Ok";
Button1->Enabled=true;
Button1->Tag=2;
}
break;
case 2:Form1->Close(); //завершить работу проги
}
}

 //читает строкку из файла
 //значение функции - к-во прочитанных символов
int GetString(int f, AnsiString *st)
{
unsigned char buf[300]; //строка(буфер)
unsigned char *p=buf;  //указатель на строку

int n; //количестыо прочитанных байт(значение ф-и FileRead)
int dl=0;//длина строки
n=FileRead(f,p,1);
while (n !=0)
{
if (*p=='\r')
{
n=FileRead (f,p,1);
break;
}
dl++;
p++;
n=FileRead (f,p,1);
}
*p='\0';
***код об который спотыкается прога*
if (dl!=0 ) st->printf("%s",buf);
*********************************
return dl;
//читает из файла целое число
int GetInt (int f)
{
char buf[20]; //строка(буфер)
char *p=buf; //указатель на строку
int n;//количество прочитанных байт(значение ф-и FileRead)
int a; //число,прочитанное из файла
n=FileRead(f,p,1);
while ((*p>='0')&& (*p<='9')&&(n>0))
{
p++;
n=FileRead(f,p,1);
}
if (*p=='\r')
n=FileRead(f,p,1);
*p='\0';
//преобразуем стрроку из буфера в целое
sscanf(buf,"%i",&a);
return a;

 


PM MAIL   Вверх
deniska
Дата 23.8.2006, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: нет
Всего: 0



Отключи галку "use dynamic rtl" может поможет (вряд ли)
Скорее всего где-то с указателями намудрил. 
CodeGuard тебе в руки
PM MAIL ICQ   Вверх
586
Дата 23.8.2006, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Нашёл ошибку: строка 141 - выход за пределы массива. А отладчик глючит, посылая на строку 180.

ЗЫ  Коли использешь VCL, можно было бы воспользоваться классом TStringList.
ЗЗЫ  Считывать файл побайтово - нехорошо.
ЗЗЗЫ Ещё я бы заменил бы int GetString(int f, AnsiString *st) на int GetString(int f, AnsiString &st). Я думаю, это бы избавило от проблемы в строке 237.
Или сделал бы так: st->operator =(buf);, а то printf для копирования строки - как-то жестоко smile

Это сообщение отредактировал(а) 586 - 23.8.2006, 14:46
PM   Вверх
veselchak
Дата 24.8.2006, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.8.2006
Где: Иркутск

Репутация: нет
Всего: нет



Спасибо, 586 ,что откликнулся на мой призыв о помощи, но возникли заковырки в моей проге:
1. я заменил  int GetString(int f, AnsiString *st) на int GetString(int f, AnsiString &st),но в ответ на это возникла ошибка E2288 Pointer to structure required on left side of -> or ->*.
2. А ошибку на 141 строке не заню как исправить.Если можешь напечатай код этой строки.

 

Это сообщение отредактировал(а) veselchak - 24.8.2006, 09:08
PM MAIL   Вверх
586
Дата 24.8.2006, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Цитата(veselchak @  24.8.2006,  10:06 Найти цитируемый пост)
int GetString(int f, AnsiString *st) на int GetString(int f, AnsiString &st),

st=buf;    // то есть работаешь со st, как с обычной строкой TAnsiString
GetString(f, str);   // вызов функции

Цитата(veselchak @  24.8.2006,  10:06 Найти цитируемый пост)
А ошибку на 141 строке не заню как исправить.Если можешь напечатай код этой строки

Цитата(veselchak @  23.8.2006,  08:01 Найти цитируемый пост)
void __fastcall TForm1::ShowVopros(TVopros v)
{
 int top;
 //int i;
 Label1->Width=ClientWidth - Label1->Left -20;
 Label1->Caption=v.Vopr;
 Label1->AutoSize=true;
 //variants
 for (i=0;i<v.nOtv;i++)
 {
  RadioButton[i]->Top=top;
  RadioButton[i]->Caption=v.Otv[i];
  RadioButton[i]->Visible=true;
  RadioButton[i]->Checked=false;
  top+=20;
 }
}



Это сообщение отредактировал(а) 586 - 24.8.2006, 10:46
PM   Вверх
veselchak
Дата 25.8.2006, 04:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.8.2006
Где: Иркутск

Репутация: нет
Всего: нет



586, как ликвидировать выход за пределы массива? 



PM MAIL   Вверх
586
Дата 25.8.2006, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Код
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include "unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//int i;
int f;//дескриптор файла теста
int level[4];//к-во правильных ответов,необходимых для достижения уровня
AnsiString mes[4]; //сообщение о достижениии уровня
TVopros Vopros; //вопрос
int otv; //номер выбранного ответа
int right=0; //к-во правильных ответов;
int i;
int dl;
//функции,обеспечивающие чтение вопроса из файла теста
int GetInt(int f); //read entire/byte
int GetString (int f,AnsiString &st); //read string
//---------------------------------------------------------------------------
 //constructor
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 //int i;
 int left=10;
 for (i=0;i<4;i++)
 {
  //создадим радиокнопки для выбора прав. ответа
  RadioButton[i]=new TRadioButton(Form1) ;
  //checked свойства
  RadioButton[i]->Parent=Form1;
  RadioButton[i]->Left=left;
  RadioButton[i]->Width=Form1->ClientWidth - Left - 20;
  RadioButton[i]->Visible=false;
  RadioButton[i]->Checked=false;
  //зададим функцию обработки события клик
  RadioButton[i]->OnClick=RadioButtonClick;
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
 AnsiString st;
 //int i;
 f=FileOpen("1.txt",fmOpenRead); //open file
 if ( f==-1 ) //если файл несуществует
 {
  Label1->Font->Style=TFontStyles()<<fsBold;
  Label1->Caption="Ошибка доступа к файлу 1.txt";
  Button1->Tag=2;
  return;
 }
 GetString(f,st);//прочитать название теста
 Form1->Caption=st;
 GetString(f,st);//прочитать вводную информацию
 Label1->Width=Form1->ClientWidth -Label1->Left-20;
 Label1->Caption=st;
 Label1->AutoSize=true;
 //прочитать информацию об уровнях оценки
 for(int i=0;i<4;i++);
 {
  level[i]=GetInt(f);
  GetString(f,mes[i]);
 }
}

//читает из файла очередной вопрос
bool GetVopros(TVopros *v)
{
 AnsiString st;
 if (GetString(f,v->Vopr) !=0)
 {
  //прочитать к-во вариантов ответа и номер правильного ответа
  v->nOtv=GetInt(f) ;
  v->rOtv=GetInt(f);
  for(int i=0;i<v->nOtv;i++); //читаем варианты ответа
  {
   GetString (f,v->Otv[i]);
  }
  return true;
 }
 else return false;
}

//выводит вопрос
void __fastcall TForm1::ShowVopros(TVopros v)
{
 int top;
 //int i;
 Label1->Width=ClientWidth - Label1->Left -20;
 Label1->Caption=v.Vopr;
 Label1->AutoSize=true;
 //variants
 for (i=0;i<v.nOtv;i++)
 {
  RadioButton[i]->Top=top;
  RadioButton[i]->Caption=v.Otv[i];
  RadioButton[i]->Visible=true;
  RadioButton[i]->Checked=false;
  top+=20;
 }
}
//щелчок на радиокнопке выбора ответа
void __fastcall TForm1::RadioButtonClick(TObject *Sender)
{
 int i=0;
 while (! RadioButton[i]->Checked)
 i++;
 otv=i+1;
 //ответ выбран,сделаем доступной кнопку  "Дальше"
 Button1->Enabled=true;
}

//удаляет вопрос с экрана
void __fastcall TForm1::EraseVopros(void)
{
 //скрыть поля выбора ответа
 for (int i=0;i<4;i++)
 {
  RadioButton[i]->Visible=false;
  RadioButton[i]->Checked=false;
 }
 //not enables button next
 Button1->Enabled=false;
}
//---------------------------------------------------------------------------

 //щелчок на кнопке Ок/Дальше/Ок
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 bool ok;//результат чтения из файла очередного вопроса
 switch (Button1->Tag)
 {
 case 0: //клик на кнопке ОК в начале работы проги,прочитать и вывести первый вопрос
  GetVopros(&Vopros);
  ShowVopros(Vopros);
  Button1->Caption=" Дальше ";
  Button1->Enabled=false;
  Button1->Tag=1;
  break;
 case 1:  //clic на кнопке Даьше
  if(otv==Vopros.rOtv)//выбран правильный ответ
   right++;
  EraseVopros();
  ok=GetVopros(&Vopros);
  if(ok)
   ShowVopros(Vopros);
  else //вопросов нет
  {
   FileClose(f);
   //вывести результата
   AnsiString st;
   int i; //number достигнутого уровня
   Form1->Caption="результат тестирования";
   st.printf("Правильных ответов:%i \ n",right);
   //определим оценку
   i=0;
   while ((right<level[i])&(i<3))
   i++;
   st=st+mes[i];
   Label1->Caption=st;
   Button1->Caption="Ok";
   Button1->Enabled=true;
   Button1->Tag=2;
  }
  break;
 case 2: Form1->Close(); //завершить работу проги
 }
}

 //читает строкку из файла
 //значение функции - к-во прочитанных символов
int GetString(int f, AnsiString &st)
{
 unsigned char buf[300]; //строка(буфер)
 unsigned char *p=buf;  //указатель на строку

 int n; //количестыо прочитанных байт(значение ф-и FileRead)
 int dl=0;//длина строки
 n=FileRead(f,p,1);
 while (n !=0)
 {
  if (*p=='\r')
  {
   n=FileRead (f,p,1);
   break;
  }
  dl++;
  p++;
  n=FileRead (f,p,1);
 }
 *p='\0';

 if (dl!=0 ) st=(char*)buf;

 return dl;
}

//читает из файла целое число
int GetInt (int f)
{
 char buf[20]; //строка(буфер)
 char *p=buf; //указатель на строку
 int n;//количество прочитанных байт(значение ф-и FileRead)
 int a; //число,прочитанное из файла
 n=FileRead(f,p,1);
 while ((*p>='0')&& (*p<='9')&&(n>0))
 {
  p++;
  n=FileRead(f,p,1);
 }
 if (*p=='\r')
 n=FileRead(f,p,1);
 *p='\0';
 //преобразуем стрроку из буфера в целое
 sscanf(buf,"%i",&a);
 // IntToStr(buf);
 return a;
}

Цитата(veselchak @  25.8.2006,  05:22 Найти цитируемый пост)
как ликвидировать выход за пределы массива

Я откуда знаю. Всё зависит от v.nOtv. Я ижу, что берешь его из файла (строка 76).
Или создавай нужное количество RadioButton'ов в цикле (строка 96).
Пока их у тебя 4. И v.nOtv>4.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0825 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.