imho.ws
IMHO.WS  

Вернуться   IMHO.WS > Компьютеры > Программирование
Опции темы
Старый 03.12.2004, 08:52     # 1
DeMx
Guest
 
Сообщения: n/a

Тестирование, на Visual C++

Нужно создаться тест. Вопрос и 4 или более вариантов ответов. Никаких заморочек не надо.
Не хочу плодить много форм (надо 10 вопросов), поэтому решил после каждого вопроса менять подписи у Radio Box'а и сам вопрос в Edit Box'е, т.е. всё будет на одной форме, но её содержание будет меняться по ходу выполнения программы. Однако тут появилась трабла - после ответа на первый вопрос, события Radio Box'ов перестаются работать. Может можно как-то обновить окно или ещё что?
Вот код:
Код:
#include "stdafx.h"
#include "TestDualityProblem.h"
#include "TestDualityProblem_2.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTestDualityProblem_2 dialog


CTestDualityProblem_2::CTestDualityProblem_2(CWnd* pParent /*=NULL*/)
	: CDialog(CTestDualityProblem_2::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTestDualityProblem_2)
	m_question = _T("");
	//}}AFX_DATA_INIT
}


void CTestDualityProblem_2::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTestDualityProblem_2)
	DDX_Text(pDX, IDC_EDIT1, m_question);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CTestDualityProblem_2, CDialog)
	//{{AFX_MSG_MAP(CTestDualityProblem_2)
	ON_BN_CLICKED(IDC_BUTTON3, OnButtonNext)
	ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
	ON_BN_CLICKED(IDC_BUTTON4, OnButtonExit)
	ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
	ON_BN_CLICKED(IDC_RADIO3, OnRadio3)
	ON_BN_CLICKED(IDC_RADIO4, OnRadio4)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestDualityProblem_2 message handlers

BOOL CTestDualityProblem_2::OnInitDialog() 
{
	CDialog::OnInitDialog();

	m_question = "Лучший игрок And1?";
	test = 1;
	q = 0;
	UpdateData(false);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CTestDualityProblem_2::OnButtonNext() 
{
	UpdateData(true);
	CStdioFile File;
	File.Open("stat.txt", CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate);
	File.SeekToEnd();
	if (test == 1) {
		File.WriteString("Вопрос 1: ");
		if (q == 2) {
			File.WriteString("правильно.");
		}
		else
			File.WriteString("не правильно.");
		test++;
	}
	if (test == 2) {
		File.WriteString("Вопрос 2: ");
		if (q == 1) {
			File.WriteString("правильно.");
		}
		else
			File.WriteString("не правильно.");
		m_question = "Лучший игрок NBA?";
		SetWindowText("Программа тестирования. Вопрос 2 из 10");
		GetDlgItem(IDC_RADIO1)->SetWindowText("Kobe Bryant");
		GetDlgItem(IDC_RADIO2)->SetWindowText("Tracy McGrady");
		GetDlgItem(IDC_RADIO3)->SetWindowText("Shaquille O'Neal");
		GetDlgItem(IDC_RADIO4)->SetWindowText("Kevin Garnett");
		test++;
		UpdateData(false);
	}
	if (test == 3) {
		File.WriteString("Вопрос 3: ");
		if (q == 1) {
			File.WriteString("правильно.");
		}
		else
			File.WriteString("не правильно.");
		m_question = "Лучший данкер Slam Nation?";
		SetWindowText("Программа тестирования. Вопрос 3 из 10");
		GetDlgItem(IDC_RADIO1)->SetWindowText("Кадур Зиани");
		GetDlgItem(IDC_RADIO2)->SetWindowText("Абдул Бамба");
		GetDlgItem(IDC_RADIO3)->SetWindowText("Саламон Сэми");
		GetDlgItem(IDC_RADIO4)->SetWindowText("Стиви Лоубел");
		test++;
		UpdateData(false);
	}
	File.Close();
}

void CTestDualityProblem_2::OnButtonExit() 
{
	int status = MessageBox( "Вы хотите выйти?", "ВЫХОД", MB_OKCANCEL | MB_ICONQUESTION );
	if (status == IDOK) exit(0);	
}

void CTestDualityProblem_2::OnRadio1() 
{
	q = 1;
}

void CTestDualityProblem_2::OnRadio2() 
{
	q = 2;	
}

void CTestDualityProblem_2::OnRadio3() 
{
	q = 3;	
}

void CTestDualityProblem_2::OnRadio4() 
{
	q = 4;	
}
Что и где надо изменить?
 
Старый 05.12.2004, 19:04     # 2
b@dger
Guest
 
Сообщения: n/a

Цитата:
DeMx:
события Radio Box'ов перестаются работать
А конкретнее?
И вообще у тебя ошибка в логике в функции void CTestDualityProblem_2::OnButtonNext(). В каждом условии стоит в конце стоит temp++ и получается так, что за один вызов этой функции все условия выполняются по порядку.
Вот так будет лучше:
Код:
void CTestDualityProblem_2::OnButtonNext() 
{
	UpdateData(true);
	CStdioFile File;
	File.Open("stat.txt", CFile::modeCreate|CFile::modeWrite|CFile::modeNoTr  uncate);
	File.SeekToEnd();

	switch(test)
	{
	case 1:
		File.WriteString("Вопрос 1: ");
		if (q == 2) {
			File.WriteString("правильно.");
		}
		else
			File.WriteString("не правильно.");
		// ВОПРОС 2
		m_question = "Лучший игрок NBA?";
		SetWindowText("Программа тестирования. Вопрос 2 из 10");
		GetDlgItem(IDC_RADIO1)->SetWindowText("Kobe Bryant");
		GetDlgItem(IDC_RADIO2)->SetWindowText("Tracy McGrady");
		GetDlgItem(IDC_RADIO3)->SetWindowText("Shaquille O'Neal");
		GetDlgItem(IDC_RADIO4)->SetWindowText("Kevin Garnett");
		break;
	case 2:
		File.WriteString("Вопрос 2: ");
		if (q == 1) {
			File.WriteString("правильно.");
		}
		else
			File.WriteString("не правильно.");

		// ВОПРОС 3
		m_question = "Лучший данкер Slam Nation?";					
		SetWindowText("Программа тестирования. Вопрос 3 из 10");
		GetDlgItem(IDC_RADIO1)->SetWindowText("Кадур Зиани");
		GetDlgItem(IDC_RADIO2)->SetWindowText("Абдул Бамба");	
		GetDlgItem(IDC_RADIO3)->SetWindowText("Саламон Сэми");
		GetDlgItem(IDC_RADIO4)->SetWindowText("Стиви Лоубел");
		break;
	case 3:
		File.WriteString("Вопрос 3: ");
		if (q == 1) {
			File.WriteString("правильно.");
		}
		else
			File.WriteString("не правильно.");

		// ВОПРОС 4
		//  ...
		//
		break;
		// И далее в том же духе...
	}
	test++;
	UpdateData(false);
}

Последний раз редактировалось b@dger; 05.12.2004 в 19:07.
 
Старый 05.12.2004, 20:26     # 3
DeMx
Guest
 
Сообщения: n/a

Да, ошибку в логике я потом сам нашёл, после публикации этой темы.
Однако дело не в этом. Попытаюсь объяснить, что происходит при выполнении программы:
Окно с заголовком "Вопрос 1 из 10". Выбираю один из Radio Box'ов, жму кнопку "Далее". Ничего не меняется. Жму ещё раз "Далее" - содержание окна меняется (меняются подписи у Radio Box'ов и Edit Box'а), заголовок теперь "Вопрос 2 из 10". Далее снова жму кнопку - окно меняется на третий вопрос...
Т.е. получается, что после первого нажатия кнопки, содержание окна почему то не изменяется, но результаты в файл записываются правильно.
Полагаю, что трабла пустиковая и абсолютно бестолковая...

Попутный вопрос: как убрать пометку у Radio Box'а? А то при переходе к следующему вопросу, в окне остаётся включённым ответ на предыдущий. Это не правильно.

Если мой проблема не понятно, то смотри вложение, там весь исходный код.
Вложения
Тип файла: rar TestDualityProblem.rar (34.0 Кбайт, 2 просмотров - Кто скачивал? )
 
Старый 05.12.2004, 22:10     # 4
b@dger
Guest
 
Сообщения: n/a

Ты опять же запутался в построенной тобой логике и невнимательно посмотрел мой код . Смотри: Когда ты нажимаешь кнопку Next, то у тебя проверяет значение test, далее обрабатывает это значение, а именно, проверяет q и записывает результат в файл, ну а затем нужно обновить данные в полях. А у тебя получается, к примеру, если test == 1 то при нажатии кнопки Next он проверяет q и записывает в файл, а затем test++. Затем, при следующем нажатии Next у тебя проверяет test, который равен 2, обрабатывает, проверяет q, записывает в файл результат, а затем только выводит 2 вопрос! Посмотри код в моем предыдущем топике повнимательнее.

Я бы на твоем месте сделал по другому: обновление полей текста вопроса и ответов зарядил в OnPaint, в зависимости от значения test. Смотри вложение. Снятие пометок чекбоксов тамже.
Вложения
Тип файла: zip TestDualityProblem_2.zip (1.5 Кбайт, 5 просмотров - Кто скачивал? )
 
Старый 06.12.2004, 00:47     # 5
DeMx
Guest
 
Сообщения: n/a

Млин, так и думал, что всё просто.
Огромное спасибо!

Теперь я задался другим вопросом.
После ответов на все вопросы, в конце хочу, чтобы показывался итоговый результат. В принципе, это не проблема, но...
При ответе на каждый из вопросов, я записываю номер ответа, сам ответ и его "правильность" в файл, плюс ещё в начале имя отвечающего, т.е. файл в итоге будет выглядеть примерно так:
--------------------------------------------
SuperMan
вопрос 1: "Helicopter" - правильно
вопрос 2: "Tracy McGrady" - не правильно
...
итог: тест пройден
--------------------------------------------
С записью всего этого в файл тоже проблем нет, разберусь. Однако как потом считать всё это и отобрать только то, что относится к текущему ответчику (в файле будет содержатся инфа не только об одном ответчике)?
Ввод имени отвечающего у меня производится в другой форме (в предыдущей).
Получается нужно в начале считать из файл последнюю строку (имя) в какую-нибудь переменную, перед тем, как начать отвечать на вопросы, затем считать весь файл, найти ранее считанное имя и вывести на экран всё, что идёт после этого имени (включая само имя).
Как вообще считать строку? Может можно как-то проще всё сделать?

Уж извиняйте меня, но новичок я в Visual Cpp...

Вспомнил ещё вопрос:
Можно ли как-то вытащить подпись у помеченного Radio Box'а (выбранного варианта)?
Понимаю, что можно так (для первого вопроса):
Код:
char answer[20];
switch(q) {
case 1:
         strcpy(answer, "Skip");
         break;
case 2:
	strcpy(answer, "Helicopter");
	break;
case 3:
	strcpy(answer, "Hot Sauce");
	break;
case 4:
	strcpy(answer, "AO");
	break;
}
Затем в дальнейшем можно использовать переменную answer для записи в файл. Но не ужели нельзя проще?
 

Опции темы

Ваши права в разделе
Вы НЕ можете создавать новые темы
Вы не можете отвечать в темах.
Вы НЕ можете прикреплять вложения
Вы НЕ можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 12:13.




Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.