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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Помогите пожалуйста, разобратся с switch! (С++, QT)  (Прочитано 25202 раз)
Андрей80
Гость
« : Март 14, 2009, 17:15 »

Здравствуйте. Помогите пожалуйста, разобратся с switch! (С++, QT)
Так получилось, что почти всегда пользовался if ... else if в своих программах =). Решил наконец избавиться от этой вредной привычки. Но увы...
Буду благодарен если кто ткнёт носом в ошибку
Код:
QString param = descriptors[descriptor];
QStringList array = param.split(";");
SqlQuery squery;
query.exec(QString(array[0]));
int j = 2;
QString var = array[1];
switch (array[1])
{
case "special" :
while (j < array.size())
{
QStringList subarr = array[j].split("=");
text += subarr[0]  + " " + squery[subarr[1]] + ", ";
j++;
}
break;

case "day" :
{text = squery[array[2]];
QStringList subarr = text.split(":");
text  = subarr[0];}
break;

case "monthNum" :
{text = squery[array[2]];
QStringList subarr = text.split(":");
text  = subarr[1];}
break;

case "yearLast2" :
{text = squery[array[2]];
QStringList subarr = text.split(":");
text  = subarr[2];
text = text.remove(0, 2);}
break;

case "art" :
text = QString :: number(IT + 1); // IT - порядковый номер записи тт Накладной
break;

default:
while (j < array.size())
{
text += array[1] + squery[array[j]];
j++;
}
}

ошибка компилятора (компилирую в QDevelop + MinGW):
error: switch quantity not an integer

PS. При использовании if else if  работает на ура
Записан
BRE
Гость
« Ответ #1 : Март 14, 2009, 17:18 »

В switch нельзя использовать строки (о чем он тебе в ошибке и говорит). Воспользуйся enum.
Код
C++ (Qt)
enum FieldType { specila, day, monthNum, yearLst, ..... };
 
FieldType fld = array[ 1 ];
switch( fld )
{
   case special:
       ....
   case day:
       ....
}
 
« Последнее редактирование: Март 14, 2009, 17:27 от BRE » Записан
Андрей80
Гость
« Ответ #2 : Март 14, 2009, 17:26 »

Спасибо!
Записан
Андрей80
Гость
« Ответ #3 : Март 14, 2009, 17:42 »

Можно ещё вопрос не по теме... Почему у вас в ответе ситаксис с подсветкой, а у меня нет
Код:
int x = 0;
switch (x)

case 0:
 x++;
break;

Записан
Khs
Гость
« Ответ #4 : Март 14, 2009, 17:51 »

Код
C++ (Qt)
int x = 0;
switch (x)
 
case 0:
x++;
break;

Выбери стиль в комбике, по стандарту там GeSHi вроде...
Записан
inst
Гость
« Ответ #5 : Апрель 12, 2009, 20:41 »

Интереса ради хочу задать такой вопрос. В стандартном примере Calculator на Qt в файле calculator.cpp есть функция unaryOperatorClicked().

В ней используется условный переход по if-else if. А вот скажите, возможно ли это как-то переделать, чтоб использовать switch? Проблема та же, что и в первом посте. Какие возможны пути решения данной задачки?
Записан
Rcus
Гость
« Ответ #6 : Апрель 12, 2009, 21:02 »

У меня была схожая проблема: при реализации сетевого протокола надо обрабатывать каждый управляющий код отдельно, поэтому в обычном варианте получается большой switch. Здесь можно попробовать использовать табличное отображение в моем случае код выглядел так:
объявление приватного класса и заполнение таблицы методов:
Код
C++ (Qt)
class MServerConnectionPrivate
{
public:
   MServerConnectionPrivate(MServerConnection *value);
   MServer *server;
   quint32 clientId;
   bool sendGreeting();
   bool processPacket(MPacket &packet);
private:
   bool processIdChange(MPacket &packet);
   bool processServerMessage(MPacket &packet);
   bool processServerStatus(MPacket &packet);
   bool processServerIdent(MPacket &packet);
   bool processServerList(MPacket &packet);
   bool processSearchResult(MPacket &packet);
   bool processCallbackRequested(MPacket &packet);
   bool processCallbackFail(MPacket &packet);
   bool processReject(MPacket &packet);
   bool processFoundSources(MPacket &packet);
   bool processFoundSourcesObfuscated(MPacket &packet);
   typedef bool (MServerConnectionPrivate::*ProcessMethodPtr)(MPacket &packet);
   typedef QHash<quint8, ProcessMethodPtr> ProcessMethodsTable;
   ProcessMethodsTable table;
   MServerConnection *q;
};
#ifdef METHOD_TABLE_FILL
#error conflict in macro declaration
#endif
#define METHOD_TABLE_FILL(_Opcode_) \
   table[Opcode::_Opcode_] = &MServerConnectionPrivate::process##_Opcode_
MServerConnectionPrivate::MServerConnectionPrivate(MServerConnection *value) : q(value), clientId(0)
{
   METHOD_TABLE_FILL(IdChange);
   METHOD_TABLE_FILL(ServerStatus);
   METHOD_TABLE_FILL(ServerMessage);
   METHOD_TABLE_FILL(ServerIdent);
   METHOD_TABLE_FILL(ServerList);
   METHOD_TABLE_FILL(SearchResult);
   METHOD_TABLE_FILL(CallbackRequested);
   METHOD_TABLE_FILL(CallbackFail);
   METHOD_TABLE_FILL(Reject);
   METHOD_TABLE_FILL(FoundSources);
   METHOD_TABLE_FILL(FoundSourcesObfuscated);
}
#undef METHOD_TABLE_FILL
применение:
Код
C++ (Qt)
bool MServerConnectionPrivate::processPacket(MPacket &packet)
{
   ProcessMethodPtr method = table[packet.opcode()];
   if (!method) {
       qFatal("Method not found for opcode = %d", packet.opcode());//TODO:remove after implementing all
       return false;
   }
   qDebug("Found method to process packet, opcode = %d", packet.opcode());
   return (this->*method)(packet);
}

Нужно только определить qHash для типа по которому строится отображение. Хотя есть сомнение, возможно есть решение попроще.
Записан
Khs
Гость
« Ответ #7 : Апрель 12, 2009, 21:23 »

А записать нужные строки в QStringList иль QMap, и делать свитч по индексам (ну или в этой области что-то) это не есть гуд?

... чето подумал, не..лучше так не делать  Подмигивающий
« Последнее редактирование: Апрель 12, 2009, 21:37 от log1c » Записан
Danila_Bagrofff
Гость
« Ответ #8 : Апрель 13, 2009, 14:42 »

всплыла трабла....

в общем свитч нормально работал по enum'ам.
Но теперь значения забиты в конф-файл, и следовательно стали переменны.
Кроме как if... else... нельзя никак заменить систему?
Код:
switch(iType)
{
     case abonent:
     //my code
    break;

    case phone:
    //my code
    break;

    case default:
   //my code
    //break
}

Раньше abonent и phone были enom'ом, а теперь int'ы. Всё, теперь нельзя никак применять такую схему?
Записан
spirit
Гость
« Ответ #9 : Апрель 13, 2009, 16:20 »

почему нельзя? приведи iType к своему перечислению и юзай свич на здоровье.
хотя и так работать должно.
Записан
Danila_Bagrofff
Гость
« Ответ #10 : Апрель 14, 2009, 07:02 »

почему нельзя? приведи iType к своему перечислению и юзай свич на здоровье.
хотя и так работать должно.

Код:
int k = 0;
int iType;

switch(iType)
{
      case k:
           break;
}

Цитировать
C:/drag/dialog.cpp:280: error: `rs' cannot appear in a constant-expression

как это привести int к enum'у? 0_o
« Последнее редактирование: Апрель 14, 2009, 07:16 от Danila_Bagrofff » Записан
spirit
Гость
« Ответ #11 : Апрель 14, 2009, 07:48 »

ну во-первых ругань идет на rs, во-вторых приводится просто
Код
C++ (Qt)
...
enum MyEnum { One = 1, Two, Three };
...
int iType = 3;
MyEnum t = MyEnum(iType);
 
switch (t) {
case One: {...}
           break;
case Two: {...}
           break;
case Three: {...}
           break;
default: {...}
           break;
};
 
покажи лучше код.
Записан
Danila_Bagrofff
Гость
« Ответ #12 : Апрель 14, 2009, 07:58 »

ЭЭ... rs это и есть k:

чуть забыл подправить код =)
Код:
int k = 0;
int iType;

switch(iType)
{
      case k:
           break;
}

Вот значения k и должны загружаться из конф-файла, а не браться из enuma. В инструкции case нужно вписывать константу. А у нас значение, вписываемое по ходу программы.
Записан
spirit
Гость
« Ответ #13 : Апрель 14, 2009, 08:04 »

ну все верно компиль ругается, тогда.
в кейсах должны быть константные значения.
читай про switch.
Записан
Danila_Bagrofff
Гость
« Ответ #14 : Апрель 14, 2009, 08:17 »

так я знаю =)

просто, думал, мож можно как-то обмануть. Просто кейсы удобнее, нежели if else =)
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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