Форум программистов, компьютерный форум CyberForum.ru

косяк вызова функции через switch case - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
Wirbelwind
0 / 0 / 0
Регистрация: 18.12.2011
Сообщений: 4
18.12.2011, 17:11     косяк вызова функции через switch case #1
! кода по моим меркам много, если решитесь помочь, запаситесь терпением)))

Итак. Имеется зародыш курсовой - игры пятнашки. делал в консоли с графикой с помощью вин32апи.
Прога разделена на 3 файла - заголовочный для класса, отдельно описание его методов, отдельно void main. Вкратце о происходящем: создается массив 4на4 объектов класса(фишек) в качестве полей имеющих координаты на поле и номер, а затем все хозяйство отрисовывается (никаких методов для выбора, движения фишек пока нет и в помине). номер фишки 0 означает свободное место на поле.

Собственно, проблема: нивкакую не отрисовывается номер последней фишки

Веселости: при изменении размера массива на 3х3 все робит, при использовании рандомно расставленных номеров баг становится плавающим - то есть то нет, зараза=(((
Кстати способ отрисовки номеров фишек крайне дебилен, ибо как с помощью TextOut'а вывести число содержащееся в типе инт так и не понял(

сам код в 3 куска


puzzle.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef PUZZLE
#define PUZZLE
#include <Windows.h>
 
class cPuzzle
    {
    public:
        cPuzzle(int xcoor = 0, int ycoor = 0, int number = 0);
        void Draw(HDC &hdc);
    private:
        int x, y, num;
    };
#endif PUZZLE

puzzle.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "Puzzle.h"
 
const int xstpos = 0;
const int ystpos = 0;
const int size = 50;
 
cPuzzle::cPuzzle(int xcoor, int ycoor, int number)
    {
        x=xcoor;
        y=ycoor;
        num=number;
    }
 
void cPuzzle::Draw(HDC &hdc)
    {
        SelectObject(hdc,GetStockObject(DC_BRUSH));
        SetDCBrushColor(hdc,RGB(255, 255, 255));
        SelectObject(hdc,GetStockObject(DC_PEN));
        SetDCPenColor(hdc,RGB(0, 0, 0));
 
        
        Rectangle(hdc, 
            xstpos+(x)*size, 
            ystpos+(y)*size,
            xstpos+(x+1)*size,
            ystpos+(y+1)*size);
 
        switch(num)
        {       
            case 1: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "1",2);break;
            case 2: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "2",2);break;
            case 3: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "3",2);break;
            case 4: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "4",2);break;
            case 5: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "5",2);break;
            case 6: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "6",2);break;
            case 7: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "7",2);break;
            case 8: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "8",2);break;
            case 9: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "9",2);break;
            case 10: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "10",2);break;
            case 11: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "11",2);break;
            case 12: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "12",2);break;
            case 13: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "13",2);break;
            case 14: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "14",2);break;
            case 15: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "15",2);break;
            default : 
                {
                    SelectObject(hdc,GetStockObject(DC_BRUSH));
                    SetDCBrushColor(hdc,RGB(127, 127, 127));
                    SelectObject(hdc,GetStockObject(DC_PEN));
                    SetDCPenColor(hdc,RGB(255, 255, 255));
 
                    Rectangle(hdc, 
                        xstpos+(x)*size, 
                        ystpos+(y)*size,
                        xstpos+(x+1)*size,
                        ystpos+(y+1)*size);
                    break;
                }
        }//end of switch
 
    }

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "Puzzle.h"
#include <stdlib.h>
#include <time.h>
#include <conio.h>
 
void main()
    {
        HWND handle = FindWindow("ConsoleWindowClass", NULL); //получаем хэндл окна
        HDC hdc = GetDC(handle);// получаем контекст устройства
        
        
        /*--------рандомное расставление фишек---------
        srand(time(NULL));
        int mass[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
        for(int i1=0;i1<16;i1++)
            {
                int i2 = rand()%15;
                int m = mass[i1];
                mass[i1]=mass[i2];
                mass[i2]=m;
            }
        */
 
        cPuzzle token[4][4];//создаем массив объектов
        int xcoor, ycoor, number=0;
        for(ycoor=0;ycoor<4;ycoor++)
            {for(xcoor=0;xcoor<4;xcoor++)
                {   //задаем значения объекту, number заменить на mass[number] для рандом. знач.
                    token[xcoor][ycoor] = cPuzzle(xcoor,ycoor,number);
                    token[xcoor][ycoor].Draw(hdc);//отрисовываем его
                    number++;
                }
            }
        _getch();  
    }
Добавлено через 1 час 5 минут
убил себя об стену. заработало если считать что "14" - 2 символа, а "15" - три
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
htonasral
5 / 5 / 1
Регистрация: 19.05.2009
Сообщений: 23
18.12.2011, 17:20     косяк вызова функции через switch case #2
Ошибка достаточно примитивная(я это даже ошибкой не считаю, просто не досмотрел).
Вообщем так:
C++
1
2
3
4
5
6
7
BOOL TextOut(
  HDC hdc,           // дескриптор DC
  int nXStart,       // x-координата начальной позиции
  int nYStart,       // y-координата начальной позиции
  LPCTSTR lpString,  // строка символов
  int cbString       // число символов
);
это функция вывода твоих циферок
параметр cbString устанавливает длину строки. Для функции ANSI, это количество BYTE (байтов).
Твоя функция:
C++
1
case 1: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "1",2);break;
C++
1
case 11: TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, "11",2);break;
То есть символ "1" это на самом деле 2 байта(+ завершающий символ '\0'), здесь все хорошо, ты и передаешь 2 байта.
Но символ "11" это уже 3 байта.
Просто нужно для чисел с 10 до 15 поменять параметр cbString на 3 и все будет работать.
Wirbelwind
0 / 0 / 0
Регистрация: 18.12.2011
Сообщений: 4
18.12.2011, 17:38  [ТС]     косяк вызова функции через switch case #3
если так сделать то все действительно с гарантией заработает))) однако числа от 10 до 14 без проблем выводятся и с параметром 2 (а он кстати не всегда обозначает байты: http://vsokovikov.narod.ru/New_MSDN_...fn_textout.htm) более того, если раскоментить рандомизацию значений, то порой и 15 будет нормально выводится
но любом случае меня пробесил блок case'ов и я пытаюсь вывести инт через TextOut
htonasral
5 / 5 / 1
Регистрация: 19.05.2009
Сообщений: 23
18.12.2011, 18:02     косяк вызова функции через switch case #4
Попробуй заменить свой switch на:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(num >=1 && num <= 15)
{
    char b[3];
    itoa(num, b, 10);
    int k = 2;
    if(num >= 10)
        {
         k = 3;
        }
    TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, b, k);
}
else
{
        SelectObject(hdc,GetStockObject(DC_BRUSH));
        SetDCBrushColor(hdc,RGB(127, 127, 127));
        SelectObject(hdc,GetStockObject(DC_PEN));
        SetDCPenColor(hdc,RGB(255, 255, 255));
 
        Rectangle(hdc, xstpos+(x)*size, ystpos+(y)*size, xstpos+(x+1)*size,
                                                ystpos+(y+1)*size);
}
Wirbelwind
0 / 0 / 0
Регистрация: 18.12.2011
Сообщений: 4
18.12.2011, 18:28  [ТС]     косяк вызова функции через switch case #5
сделал так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void cPuzzle::Draw(HDC &hdc)
    {
        if(num >=1 && num <= 15)
            {
                Rectangle(hdc, 
                    xstpos+(x)*size, 
                    ystpos+(y)*size,
                    xstpos+(x+1)*size,
                    ystpos+(y+1)*size);
                char b[3];
                itoa(num, b, 10);
                int k=(num>9)? 3 : 2;
                TextOut(hdc, xstpos+(x)*size + 15, ystpos+(y)*size + 15, b, k);
            }
        else
            {
                SelectObject(hdc,GetStockObject(DC_BRUSH));
                SetDCBrushColor(hdc,RGB(127, 127, 127));
                SelectObject(hdc,GetStockObject(DC_PEN));
                SetDCPenColor(hdc,RGB(255, 255, 255));
 
                Rectangle(hdc, 
                    xstpos+(x)*size, 
                    ystpos+(y)*size,
                    xstpos+(x+1)*size,
                    ystpos+(y+1)*size);
        
                SelectObject(hdc,GetStockObject(DC_BRUSH));
                SetDCBrushColor(hdc,RGB(255, 255, 255));
                SelectObject(hdc,GetStockObject(DC_PEN));
                SetDCPenColor(hdc,RGB(0, 0, 0));
            }
    }
Цитата Сообщение от htonasral Посмотреть сообщение
itoa(num, b, 10);
расскажи что там означает число 10 и я прям тебя расцелую)))
htonasral
5 / 5 / 1
Регистрация: 19.05.2009
Сообщений: 23
18.12.2011, 18:41     косяк вызова функции через switch case #6
По поводу сколько же байт ставить.
Точно я не знаю, но в описании функции написано что передаваемая строка в функцию должна быть без символа конца строки, вот почему там ставится количество байт после строки(чтобы знать сколько символов выводить, а не всю строку целиком).
Так же не понятно какой именно набор использует программа, нашел вот такое:
В MSDN описано, что LPCTSTR это 32 битный указатель на строку для совместимости с UNICODE и DBCS.
То есть если этот параметр принимает DBCS(набор двухбайтных символов), то должно быть так как я и писал:
строка "1" - 2 байта, строка "11" - должна вообще-то даже быть 4 байта. Но с 4 байтами выводит кашу.
Вообщем непонятно.

Добавлено через 2 минуты
На счет функции itoa, мог бы уже не полениться и посмотреть что она принимает, но так как я начал уже писать то скажу, это система счисления в которой нужно записать число в массив символов, 10 - то есть десятичная.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.12.2011, 18:59     косяк вызова функции через switch case
Еще ссылки по теме:

Case switch и функции C++
Упрощение вызова функции через #define C++
C++ Оптимизируется ли компилятором конструкция switch-case? Работа со строками через ID объекта или hash

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Wirbelwind
0 / 0 / 0
Регистрация: 18.12.2011
Сообщений: 4
18.12.2011, 18:59  [ТС]     косяк вызова функции через switch case #7
вчера полтора часа искал функцию, которая перевела бы int в char
премного благодарен:dance3:
Yandex
Объявления
18.12.2011, 18:59     косяк вызова функции через switch case
Ответ Создать тему
Опции темы

Текущее время: 09:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru