Russian Qt Forum
Ноябрь 28, 2024, 05:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Выход из цикла по условию  (Прочитано 9605 раз)
nkly777
Гость
« : Март 30, 2007, 11:05 »

У меня в программе есть функция которая читает символы из com порта и складывает их в строку QString. Выход из функции должен происходить по одному из трех условий
1 Получена комбинация "PASSWORD <"
2 Получена комбинация "<"
3 По истечении определенного времени

Вот код этой функции
Код:

int Tread::readATS(void)
{
std::cout <<"начало работы readATS"<<std::endl;
QChar ch;
QString str;
QTime t;
int value = 0;
int timeout =5000; /**Время ожидания приглашения ввода пароля или команды**/
t.start();

while(t.elapsed() <= timeout)
{
ch=fgetc(port);
std::cout<<ch.toAscii();
str=str+ch;
if(str.contains("<",Qt::CaseInsensitive))
{
if(str.contains("PASSWORD",Qt::CaseSensitive))
{
value=1;
std::cout<<"Запрос пароля"<<std::endl;
break;
}
value=2;
std::cout<<"Введите команду"<<std::endl;
break;
}
}
std::cout <<"Завершение работы readATS"<<std::endl;
return value;
}


Если приходит "PASSWORD <" то выход все равно происходит как будто пришло "<"
Что неправильно? Как сделать правильно?

PS Вывод в std я вставил для отладки
Записан
Mikhail
Программист
*****
Offline Offline

Сообщений: 587


Просмотр профиля
« Ответ #1 : Март 30, 2007, 12:47 »

Не полная информация в вопросе.
Где вызвается readATS(void)?
Если Tread - нить, то где ее функция run().
Записан
nkly777
Гость
« Ответ #2 : Март 30, 2007, 13:09 »

Функция readATS(void) вызывается в нити Tread
Привожу ее функцию run()
Код:

void Tread::run()
{
answer=rd_wr_port( zapros);
}

Реализация функции rd_wr_port(zapros) следующая
Код:

QString Tread::rd_wr_port(QString zapros)
{
QString otvet;
desc_port=open_port();
init_raw_tty( desc_port);
port = fdopen( desc_port, "w+b" );
tcsendbreak(desc_port,400);
tcflush(desc_port, TCIFLUSH);
int v=readATS();    // Вызов функции readATS()
tcflush(desc_port,TCIFLUSH);
std::cout<<"v="<<v<<std::endl;
tcflush(desc_port,TCIFLUSH);
switch(v)
{
case 0:
{
std::cout<<"readATS() вернула 0, истек период ожидания"<<std::endl;
break;
}
case 1:
{ //PASSWORD
sendpassword(port);
usleep(500000);
sendcommand(zapros);
otvet=getreport();
break;
}
case 2:
{ //Команда
sendcommand(zapros);
otvet=getreport();
break;
}
default:
{
std::cout<<"Функция readATS() вернула "<<v<<" неизвестный ответ."<<std::endl;
}
}

fclose(port);
close(desc_port);
return otvet;
}


Порт открываю со следующими параметрами
Код:

void Tread::init_raw_tty(int desc_port)
{
struct termios newtio;

bzero(&newtio,sizeof(newtio)); //Очищаем структуру newtio
//---------------------------------------------------------1200 BOD,cs7|1,parenb
  newtio.c_cc[VTIME]    = 1;
   newtio.c_cc[VMIN]     = 0;
newtio.c_cflag &=~(CSTOPB|CS5|CS6|CS7|CS8|PARENB|PARODD);
newtio.c_cflag |=(CS7|PARENB|CREAD|CLOCAL);
cfsetospeed(&newtio, B1200);
cfsetispeed(&newtio, B1200);
//------------------------------------------------------------------------------------------------------------------------------
    tcflush(desc_port, TCIFLUSH);
    tcsetattr(desc_port,TCSANOW,&newtio);
}
Записан
SABROG
Гость
« Ответ #3 : Март 30, 2007, 13:31 »

Ну я и не удивлен, у тебя 2 break'a стоит и на получение пароля и на получение символа "<"
Код:

      if(str.contains("<",Qt::CaseInsensitive))
         {
            if(str.contains("PASSWORD",Qt::CaseSensitive))
               {
                  value=1;
                  std::cout<<"Запрос пароля"<<std::endl;
                  break; // РАЗ
               }
            value=2;
            std::cout<<"Введите команду"<<std::endl;
            break; // ДВАЗ
         }


Оба обрубают цикл while
Записан
nkly777
Гость
« Ответ #4 : Март 30, 2007, 13:59 »

Ну так мне и нужно сделать break либо по РАЗ либо по ДВА. Насколько я понимаю при получении PASSWORD выполнится break РАЗ и произойдет выход из цикла WHILE, а break ДВА при этом пробросится. Или я неправ?? Тогда как правильно?
Записан
SABROG
Гость
« Ответ #5 : Март 30, 2007, 15:00 »

Цитата: "nkly777"
Ну так мне и нужно сделать break либо по РАЗ либо по ДВА. Насколько я понимаю при получении PASSWORD выполнится break РАЗ и произойдет выход из цикла WHILE, а break ДВА при этом пробросится. Или я неправ?? Тогда как правильно?


Цитировать

Если приходит "PASSWORD <" то выход все равно происходит как будто пришло "<"


Ты определись что тебе нужно... break ДВА никуда не пробросится, а ровно также выйдет из цикла WHILE.
Записан
nkly777
Гость
« Ответ #6 : Март 30, 2007, 15:16 »

Ты хочешь сказать что break РАЗ не прервет цикл while() а выполнит команду value=2;
Но оператор break - это оператор безусловного выхода из цикла, следовательно если в str обнаружится PASSWORD то должно выполниться value=1и выход из цикла WHILE()
Записан
SABROG
Гость
« Ответ #7 : Март 30, 2007, 15:35 »

Оба брейка выведут из цикла, ты сам написал, что этого хочешь, ты также написал, что тебе не нравится, что цикл прерывается при нахождении символа "<"...
Записан
nkly777
Гость
« Ответ #8 : Март 30, 2007, 16:12 »

Наверное я неправильно объясняю.
В порт может прийти последовательность символов (включая непечатные символы и символы перевода строки) произвольной длины которая заканчивается следующей комбинацией PASSWORD <
В этом случае мне нужно послать пароль и в случае удачного коннекта послать некие команды.
В порт также может прийти последовательность символов (включая непечатные символы и символы перевода строки) произвольной длины которая заканчивается символом "<"
В этом случае мне не нужно посылать пароль а нужно сразу отправить определенную комаду.
Так вот как мне различить какая у меня ситуация, что мне нужно, вводить пароль или посылать команду?Непонимающий
У меня почему-то получается что всегда мне надо вводить команду (функция возвращает value=2) хотя реально иногда нужно вводить пароль(функция должна возвращать value=1)
Записан
SABROG
Гость
« Ответ #9 : Март 30, 2007, 17:50 »

У тебя неправильно сделано, ты ищешь сначала знак "<" и потом делаешь выводы. Но "PASSWORD <" сам по себе имеет такой символ, отсюда и косяки начинаются.
Тебе надо искать сначала "PASSWORD <", и если строка его не содержит, то уже потом искать "<"
Записан
Mikhail
Программист
*****
Offline Offline

Сообщений: 587


Просмотр профиля
« Ответ #10 : Март 30, 2007, 20:02 »

Твоя нить сработает только один раз и завершится.
Вообще то она нужна при работе с портом постоянно.
Из нити полученная информация должна передаваться в блок анализа.
У тебя же анализ заверщает нить.
Записан
Вудруф
Гость
« Ответ #11 : Апрель 02, 2007, 07:12 »

SABROG - по-моему, ты чего-то не то говоришь. Если строка содержит "PASSWORD <", то сработают оба условия, и программа должна выйти по break номер РАЗ.
Другое дело, что те же if'ы сработают для строки "1 < 2 && PASSWORD > 5".
Записан
nkly777
Гость
« Ответ #12 : Апрель 02, 2007, 14:06 »

Функция readATS() работает правильно. Проблема оказалась совсем в другом месте.При обращении к порту функция читала не то что реально передавала станция, а то что оставалось в буферах от прошлых попыток чтения. Вставил дополнительные функции очистки com порта перед обращением к нему, теперь вроде работает нормально.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 23.