Еще один нубский вопрос)
В общем имеем TextBox, 2 кнопки. При нажатии первой кнопки через диалоговое окно выбираю открываемый текстовый файл, из которого построчно читается текст и выводится, пока не встретится строка "***". После этого события нужно дождаться нажатия второй кнопки и вывести в текстовое поле, ну пока что любой текст, а вообще будет обрабатываться событие проверки правильности ответа. Ну это неважно. Реализую это все так:
Код:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ ) {
otvet = "1";
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ ) {
// по нажатию кнопки 3 открывается нужный файл и запускается код. выводящий в textBox вопрос и варианты ответа
OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
openFileDialog1->InitialDirectory = "d:\\";
openFileDialog1->Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1->FilterIndex = 2;
openFileDialog1->RestoreDirectory = true;
if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK ) //если нажата Ок в диалоговом окне
{ String^ filename = openFileDialog1->FileName;
try {
StreamReader^ sr = gcnew StreamReader(filename,System::Text::Encoding::Default); //Default использует
String^ line, ^line1, ^otvet; //текущее значение системной локали
while ((line = sr->ReadLine()) != nullptr) {
if (line!= "***"){
line1 += line + Environment::NewLine;
textBox1->Text = line1 + Environment::NewLine;};
if (line = "***"){
do {}
while (otvet!="1");
textBox1->Text = "ФОРЕВАААА";
}
otvet = "1";
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ ) {
// по нажатию кнопки 3 открывается нужный файл и запускается код. выводящий в textBox вопрос и варианты ответа
OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
openFileDialog1->InitialDirectory = "d:\\";
openFileDialog1->Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1->FilterIndex = 2;
openFileDialog1->RestoreDirectory = true;
if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK ) //если нажата Ок в диалоговом окне
{ String^ filename = openFileDialog1->FileName;
try {
StreamReader^ sr = gcnew StreamReader(filename,System::Text::Encoding::Default); //Default использует
String^ line, ^line1, ^otvet; //текущее значение системной локали
while ((line = sr->ReadLine()) != nullptr) {
if (line!= "***"){
line1 += line + Environment::NewLine;
textBox1->Text = line1 + Environment::NewLine;};
if (line = "***"){
do {}
while (otvet!="1");
textBox1->Text = "ФОРЕВАААА";
}
Ну и, соответственно, при нажатии первой button3 и выборе открываемого файла все зависает). Насколько понимаю, событие нажатия button1 просто не успевает пробиться в цикл do....while. B том же бейсике и паскале , если склероз не изменяет, такое лечилось вставкой паузы. Как это делается в vc++? Или тут более глубокая ошибка? Заранее спасибо за ответ)
Клик на button1 само по себе событие, почему бы не осуществлять нужные действия(вывод textBox1->Text = "ФОРЕВАААА"; и т.п.) как раз по нажатию кнопки button1?
Если необходимо выполнять действия button1 только после button3, можно button1 сделать неактивной в designtime а при нажатии button3 активировать ее.
Или если лишь часть действий button1 не должна выполняться до button3 задействовать глобальную bool переменную.
Пауза, мб и могла бы решить проблему, но какой смысл изобретать отлов события?
Не много в другую сторону : А не лучше было бы задавать св-ва OpenFileDialog в designtime? А то задавать одни и те же значения при каждом нажатии button3.. Имеет смысл?
интернета не было-потому не отвечал.. клик на button3 стартует тест,который открывает текстовый файл,собственно содержащий этот тест,выводит вопрос и варианты ответа в текстовое поле. если строка состоит из 3х звездочек,это метка, после чего вывод содержимого текстового файла приостонавливается, пока пользователь не введет в текстовое поле#2 вариант ответа и не нажмет button2.этот клик изменяет счетчик правильных ответов итп, после чего выводятся новые вопрос с ответами. такой был план)
Код:
#include <iostream>
#include <fstream>
TSDIAppForm *SDIAppForm;
unsigned int now;
unsigned int trcnt;
ifstream in;
UnicodeString prv;
//---------------------------------------------------------------------
__fastcall TSDIAppForm::TSDIAppForm(TComponent *AOwner)
: TForm(AOwner)
{
now = 0;
trcnt = 0;
prv = (UnicodeString)"1";
}
//---------------------------------------------------------------------------
bool compare(char * str1, char * str2)
{
bool b = 1;
for(unsigned int i = 0;((str1 != '\0') && (str2 != '\0') && b);i++)
if(str1 != str2)
b = 0;
return b;
}
//---------------------------------------------------------------------------
bool compare(wchar_t * str1, wchar_t * str2)
{
bool b = 1;
for(unsigned int i = 0;((str1 != '\0') && (str2 != '\0') && b);i++)
if(str1 != str2)
b = 0;
return b;
}
//---------------------------------------------------------------------------
void __fastcall TSDIAppForm::Read(TObject *Sender)
{
Memo1->Lines->Clear();
char * line = new char [50];
in.getline(line,50,'\n');
while(!compare(line,"***"))
{
Memo1->Lines->Add((UnicodeString)line);
in.getline(line,50,'\n');
}
}
//---------------------------------------------------------------------------
void __fastcall TSDIAppForm::Button2Click(TObject *Sender)
{
wchar_t * filename = new wchar_t [50];
OpenDialog1->Execute();
filename = OpenDialog1->FileName.c_str();
SetCurrentDirectory(ExtractFilePath(filename).c_str());
in.open(ExtractFileName(filename).c_str(),ios::in);
Read(Sender);
Button1->Enabled = 1;
}
//---------------------------------------------------------------------------
void __fastcall TSDIAppForm::Button1Click(TObject *Sender)
{
// char * tmp = (char *)Edit1->Text.c_str();
if(compare(Edit1->Text.c_str(),prv.c_str()))
trcnt++;
now++;
if(!in.eof())
Read(Sender);
else
{
Button1->Enabled = 0;
ShowMessage((trcnt/now)*100);
}
Edit1->Clear();
}
//---------------------------------------------------------------------------
#include <fstream>
TSDIAppForm *SDIAppForm;
unsigned int now;
unsigned int trcnt;
ifstream in;
UnicodeString prv;
//---------------------------------------------------------------------
__fastcall TSDIAppForm::TSDIAppForm(TComponent *AOwner)
: TForm(AOwner)
{
now = 0;
trcnt = 0;
prv = (UnicodeString)"1";
}
//---------------------------------------------------------------------------
bool compare(char * str1, char * str2)
{
bool b = 1;
for(unsigned int i = 0;((str1 != '\0') && (str2 != '\0') && b);i++)
if(str1 != str2)
b = 0;
return b;
}
//---------------------------------------------------------------------------
bool compare(wchar_t * str1, wchar_t * str2)
{
bool b = 1;
for(unsigned int i = 0;((str1 != '\0') && (str2 != '\0') && b);i++)
if(str1 != str2)
b = 0;
return b;
}
//---------------------------------------------------------------------------
void __fastcall TSDIAppForm::Read(TObject *Sender)
{
Memo1->Lines->Clear();
char * line = new char [50];
in.getline(line,50,'\n');
while(!compare(line,"***"))
{
Memo1->Lines->Add((UnicodeString)line);
in.getline(line,50,'\n');
}
}
//---------------------------------------------------------------------------
void __fastcall TSDIAppForm::Button2Click(TObject *Sender)
{
wchar_t * filename = new wchar_t [50];
OpenDialog1->Execute();
filename = OpenDialog1->FileName.c_str();
SetCurrentDirectory(ExtractFilePath(filename).c_str());
in.open(ExtractFileName(filename).c_str(),ios::in);
Read(Sender);
Button1->Enabled = 1;
}
//---------------------------------------------------------------------------
void __fastcall TSDIAppForm::Button1Click(TObject *Sender)
{
// char * tmp = (char *)Edit1->Text.c_str();
if(compare(Edit1->Text.c_str(),prv.c_str()))
trcnt++;
now++;
if(!in.eof())
Read(Sender);
else
{
Button1->Enabled = 0;
ShowMessage((trcnt/now)*100);
}
Edit1->Clear();
}
//---------------------------------------------------------------------------
Да неважно) мне важнее разобраться что да как, чем код готовый получить. Так вот ....
Изначально я и хотел читать файл. используя iostream.. Только вот оказывается. что внутри Form1.h использовать iostream-овские команды, функции и методы не получается, потому и использую Stream.
Почему так, кто может подсказать? Может у меня и остальное в понимание войдет...
Опять же раз не удается прерывать процесс чтения, попробовал вчера запихнуть все в массив... vector не удается подключить ((( вот скорее всего по той же причине, что и раньше с std...
Разбираюсь с Array.. Как считаете, стоит таким способом решать задачу? Ну т.е. по button3 выбирается файл, читается построчно в массив, например в
Код:
public:static array <System::String^> ^myIntArray;
а затем уже по каждому нажатию button 2 читать строки массива? Или это Bread (хлеб по англиЦки?)
Я не понял,тут просто C++,BCB какой-нибудь или всё же MC++?Почти всё указывает на последнее,так зачем же делать такую кучу всего,а потом ещё и удивляться,отчего оно не работает?
Вот тот же пример с std.. Использовать функции пространства имен std можно в главном файле проекта, а если попытаться в Form1.h, то такого пространства не существует. Вот и копаюсь больше на NET Framework 3.5. Просто потому что хоть что-то получаться стало...Ну это мы отклонились от темы)
Так что вы подразумеваете под "кучей всего"?
организовал строковый массив, куда запихнул построчно весь файл. Потом организовал проверку элементов массива. Как-то так..... Вот два кусочка, относящиеся к действиям с кнопками 1 и 3:
Код:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ ) {
int i, metka=0; // метка устанавливается "в ноль" для анализа первой строки "блока", содержащей информацию о правильном ответе
i=const1+1; SumOtv++; // счетчик цикла устанавливается равным const1+1, т.е. на 1 больше индекса последнего выведенного элемента
// массива, которым являлась строка "***". Кроме того инкрементируется переменная SumOtv, являющаяся
// счетчиком отвеченых вопросов
String^ line, ^line1; // объявление переменных для работы со строковыми элементами массива myArr1
myotvet = textBox3->Text; // переменной myotvet присваивается значение, введенное в текстовом поле textBox3
// выполняем проверку на правильность ответа, т.е. соответствие ответа пользователя myotvet и // правильного ответа. считанного из файла
if (otvet==myotvet) {textBox2->Text = "Ответ ВЕРЕН!";PravOtv++;}
// если ответ верен, т.е. otvet==myotvet, то выводится информация об этом событии и инкрементируется счетчик правильных ответов PravOtv, иначе выводится
// пользователь информируется об ошибке и получает информацию о правильном ответе
else {textBox2->Text = "Вы ошиблись!!! Правильный ответ: " + otvet;}
// цикл, используемый для чтения элементов массива и получения информации об очередном правильном ответе, а также выводе очередного вопроса и вариантов ответа следующего "блока"
for (i;i<Lmass;i++)
{line = myArr1->GetValue( i )->ToString();
// если метка metka установлена в 0, то значит анализируем строку, содержащую информацию о правильном ответе, если нет,
// то правильный ответ уже получен и требуется вывод строк, пока не "встретим" строку "***" - метка окончания "блока"
if (metka == 0) {
if (line == "Ответ№1") {otvet="1"; metka = 1;}
if (line == "Ответ№2") {otvet="2"; metka = 1;}
if (line == "Ответ№3") {otvet="3"; metka = 1;}
if (line == "Ответ№4") {otvet="4"; metka = 1;}
if (line == "Ответ№5") {otvet="5"; metka = 1;}
if (line == "Ответ№6") {otvet="6"; metka = 1;}
if (line == "Ответ№7") {otvet="7"; metka = 1;}
if (line == "Ответ№8") {otvet="8"; metka = 1;}
if (line == "Ответ№9") {otvet="9"; metka = 1;}
if (line == "Ответ№10") {otvet="10"; metka = 1;}
if (line == "Ответ№11") {otvet="11"; metka = 1;}
if (line == "Ответ№12") {otvet="12"; metka = 1;}
if (line == "Ответ№13") {otvet="13"; metka = 1;}
if (line == "Ответ№14") {otvet="14"; metka = 1;}
if (line == "Ответ№15") {otvet="15"; metka = 1;}
if (line == "Конец!") {metka = 0; Ball= PravOtv * 100 / SumOtv; button1->Hide();
if (Ball == 100) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '5'";}
if (Ball >= 80 && Ball<100) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '4'";}
if (Ball >= 60 && Ball<80) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '3'";}
if (Ball<60) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '2'";}
}
}
else {
if (line != "***") {line1 += line + Environment::NewLine; textBox1->Text = line1;}
else {const1=i; i=Lmass;}
// "сохранение" индекса последнего прочитанного элемента массива, присвоение счетчику значения Lmass для выхода из цикла
}
}
}
*********************************************
// кнопка 3 НАЧАТЬ определяет какой файл открыть и начинает работу
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ ) {
// по нажатию кнопки 3 открывается нужный файл и запускается код. выводящий в textBox вопрос и варианты ответа
int i=0, metka=0; // i - инициализация счетчика, metka - инициализация метки для контроля строки, содержащей "правильный вопрос"
textBox1->ResetText();
textBox2->ResetText();
OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
openFileDialog1->InitialDirectory = "d:\\";
openFileDialog1->Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1->FilterIndex = 2;
openFileDialog1->RestoreDirectory = true;
if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK ) //если нажата Ок в диалоговом окне
{ String^ filename = openFileDialog1->FileName;
try {
StreamReader^ sr = gcnew StreamReader(filename,System::Text::Encoding::Default);
String^ line, ^line1;
while ((line = sr->ReadLine()) != nullptr) {
// пока не закончится файл. его содержимое построчно заносится в массив myArr1
// i - это счетчик для индикации массива myArr1, значение которого затем присваивается переменной Lmass - размерность массива
// изначально равная 1000 (я так решил) после прочтения для экономии памяти изменяется на реальное число строк
myArr1->SetValue(line, i);
i++;
Lmass=i;
}
// нижеследующий код выводит в textBox1 первый "блок" т.е. первый вопрос и варианты ответа.
// Вывод следующих блоков осуществляется по нажатию Button1
i=0; metka=0; SumOtv=0; PravOtv=0; //SumOtv - обнуление счетчика числа ответов, PravOtv - обнуление счетчика правильных ответов
// в данном цикле для вывода первого блока осуществляется проверка очередного элемента на равенство "строке-метке ("***")
// и в случае если это строка метка, то выполнение цикла прерывается путем присвоения счетчику i значения lmass, т.е.
// выполнение условия окончания цикла
button1->Show();
for (i;i<=Lmass;i++)
{line = myArr1->GetValue( i )->ToString();
if (metka == 0) {
if (line == "Ответ№1") {otvet="1"; metka = 1;}
if (line == "Ответ№2") {otvet="2"; metka = 1;}
if (line == "Ответ№3") {otvet="3"; metka = 1;}
if (line == "Ответ№4") {otvet="4"; metka = 1;}
if (line == "Ответ№5") {otvet="5"; metka = 1;}
if (line == "Ответ№6") {otvet="6"; metka = 1;}
if (line == "Ответ№7") {otvet="7"; metka = 1;}
if (line == "Ответ№8") {otvet="8"; metka = 1;}
if (line == "Ответ№9") {otvet="9"; metka = 1;}
if (line == "Ответ№10") {otvet="10"; metka = 1;}
if (line == "Ответ№11") {otvet="11"; metka = 1;}
if (line == "Ответ№12") {otvet="12"; metka = 1;}
if (line == "Ответ№13") {otvet="13"; metka = 1;}
if (line == "Ответ№14") {otvet="14"; metka = 1;}
if (line == "Ответ№15") {otvet="15"; metka = 1;}
}
else {
if (line != "***") {line1 += line + Environment::NewLine; textBox1->Text = line1;}
else {const1=i; i=Lmass;}
}
}
}
catch (Exception^ ) { this->~Form1();
}
}
}
};
int i, metka=0; // метка устанавливается "в ноль" для анализа первой строки "блока", содержащей информацию о правильном ответе
i=const1+1; SumOtv++; // счетчик цикла устанавливается равным const1+1, т.е. на 1 больше индекса последнего выведенного элемента
// массива, которым являлась строка "***". Кроме того инкрементируется переменная SumOtv, являющаяся
// счетчиком отвеченых вопросов
String^ line, ^line1; // объявление переменных для работы со строковыми элементами массива myArr1
myotvet = textBox3->Text; // переменной myotvet присваивается значение, введенное в текстовом поле textBox3
// выполняем проверку на правильность ответа, т.е. соответствие ответа пользователя myotvet и // правильного ответа. считанного из файла
if (otvet==myotvet) {textBox2->Text = "Ответ ВЕРЕН!";PravOtv++;}
// если ответ верен, т.е. otvet==myotvet, то выводится информация об этом событии и инкрементируется счетчик правильных ответов PravOtv, иначе выводится
// пользователь информируется об ошибке и получает информацию о правильном ответе
else {textBox2->Text = "Вы ошиблись!!! Правильный ответ: " + otvet;}
// цикл, используемый для чтения элементов массива и получения информации об очередном правильном ответе, а также выводе очередного вопроса и вариантов ответа следующего "блока"
for (i;i<Lmass;i++)
{line = myArr1->GetValue( i )->ToString();
// если метка metka установлена в 0, то значит анализируем строку, содержащую информацию о правильном ответе, если нет,
// то правильный ответ уже получен и требуется вывод строк, пока не "встретим" строку "***" - метка окончания "блока"
if (metka == 0) {
if (line == "Ответ№1") {otvet="1"; metka = 1;}
if (line == "Ответ№2") {otvet="2"; metka = 1;}
if (line == "Ответ№3") {otvet="3"; metka = 1;}
if (line == "Ответ№4") {otvet="4"; metka = 1;}
if (line == "Ответ№5") {otvet="5"; metka = 1;}
if (line == "Ответ№6") {otvet="6"; metka = 1;}
if (line == "Ответ№7") {otvet="7"; metka = 1;}
if (line == "Ответ№8") {otvet="8"; metka = 1;}
if (line == "Ответ№9") {otvet="9"; metka = 1;}
if (line == "Ответ№10") {otvet="10"; metka = 1;}
if (line == "Ответ№11") {otvet="11"; metka = 1;}
if (line == "Ответ№12") {otvet="12"; metka = 1;}
if (line == "Ответ№13") {otvet="13"; metka = 1;}
if (line == "Ответ№14") {otvet="14"; metka = 1;}
if (line == "Ответ№15") {otvet="15"; metka = 1;}
if (line == "Конец!") {metka = 0; Ball= PravOtv * 100 / SumOtv; button1->Hide();
if (Ball == 100) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '5'";}
if (Ball >= 80 && Ball<100) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '4'";}
if (Ball >= 60 && Ball<80) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '3'";}
if (Ball<60) {textBox1->Text = "% Правильных ответов составляет " + Ball + "% Ваша оценка = '2'";}
}
}
else {
if (line != "***") {line1 += line + Environment::NewLine; textBox1->Text = line1;}
else {const1=i; i=Lmass;}
// "сохранение" индекса последнего прочитанного элемента массива, присвоение счетчику значения Lmass для выхода из цикла
}
}
}
*********************************************
// кнопка 3 НАЧАТЬ определяет какой файл открыть и начинает работу
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ ) {
// по нажатию кнопки 3 открывается нужный файл и запускается код. выводящий в textBox вопрос и варианты ответа
int i=0, metka=0; // i - инициализация счетчика, metka - инициализация метки для контроля строки, содержащей "правильный вопрос"
textBox1->ResetText();
textBox2->ResetText();
OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
openFileDialog1->InitialDirectory = "d:\\";
openFileDialog1->Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1->FilterIndex = 2;
openFileDialog1->RestoreDirectory = true;
if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK ) //если нажата Ок в диалоговом окне
{ String^ filename = openFileDialog1->FileName;
try {
StreamReader^ sr = gcnew StreamReader(filename,System::Text::Encoding::Default);
String^ line, ^line1;
while ((line = sr->ReadLine()) != nullptr) {
// пока не закончится файл. его содержимое построчно заносится в массив myArr1
// i - это счетчик для индикации массива myArr1, значение которого затем присваивается переменной Lmass - размерность массива
// изначально равная 1000 (я так решил) после прочтения для экономии памяти изменяется на реальное число строк
myArr1->SetValue(line, i);
i++;
Lmass=i;
}
// нижеследующий код выводит в textBox1 первый "блок" т.е. первый вопрос и варианты ответа.
// Вывод следующих блоков осуществляется по нажатию Button1
i=0; metka=0; SumOtv=0; PravOtv=0; //SumOtv - обнуление счетчика числа ответов, PravOtv - обнуление счетчика правильных ответов
// в данном цикле для вывода первого блока осуществляется проверка очередного элемента на равенство "строке-метке ("***")
// и в случае если это строка метка, то выполнение цикла прерывается путем присвоения счетчику i значения lmass, т.е.
// выполнение условия окончания цикла
button1->Show();
for (i;i<=Lmass;i++)
{line = myArr1->GetValue( i )->ToString();
if (metka == 0) {
if (line == "Ответ№1") {otvet="1"; metka = 1;}
if (line == "Ответ№2") {otvet="2"; metka = 1;}
if (line == "Ответ№3") {otvet="3"; metka = 1;}
if (line == "Ответ№4") {otvet="4"; metka = 1;}
if (line == "Ответ№5") {otvet="5"; metka = 1;}
if (line == "Ответ№6") {otvet="6"; metka = 1;}
if (line == "Ответ№7") {otvet="7"; metka = 1;}
if (line == "Ответ№8") {otvet="8"; metka = 1;}
if (line == "Ответ№9") {otvet="9"; metka = 1;}
if (line == "Ответ№10") {otvet="10"; metka = 1;}
if (line == "Ответ№11") {otvet="11"; metka = 1;}
if (line == "Ответ№12") {otvet="12"; metka = 1;}
if (line == "Ответ№13") {otvet="13"; metka = 1;}
if (line == "Ответ№14") {otvet="14"; metka = 1;}
if (line == "Ответ№15") {otvet="15"; metka = 1;}
}
else {
if (line != "***") {line1 += line + Environment::NewLine; textBox1->Text = line1;}
else {const1=i; i=Lmass;}
}
}
}
catch (Exception^ ) { this->~Form1();
}
}
}
};