Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Указатель на строку в структуре
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
011119xx
Нужна помощь опытных специалистов.

Код такой:
Код
typedef struct
{
     int               x_numicons;                
     int               y_numicons;                
     int               iconnumber[10];            
} imenu_icons_t;

typedef struct
{
     imenu_icons_t      *menu_idle;                
     imenu_icons_t      *menu_active;          
     imenu_icons_t      *menu_icon;              
     char               *menu_text[10];            
} imenu_t;

imenu_icons_t main_icon = {1, 1, {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};

imenu_icons_t main_idle = {10, 1, {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}};

imenu_icons_t main_active = {10, 1, {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}};

const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};

int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i;
     char *ptr;

//     В функции показано не все, поэтому пусть не смущает ее бессмысленность

     for(i = 0; i < entries; i++)
     {
           ptr = (char *)pmenu->menu_text[i];
     }

     return current;
}

unsigned char ic;

void main(void)
{
     ic = icon_menu(&mainmenu);
}

беспокоит строка: ptr = (char *)pmenu->menu_text[i];
так как сейчас она указывает не туда куда хотелось бы. Вопрос в том как это правильно сделать, т.е. чтобы указатель указывал на строку?
Палыч
Цитата(011119xx @ Aug 3 2011, 15:18) *
как это правильно сделать, т.е. чтобы указатель указывал на строку?
Скорее всего, так:
Код
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, {main_text[0], main_text[2], main_text[3], main_text[4], main_text[5], main_text[6], main_text[7], main_text[8], main_text[9] } };

ISK2010
Лучше работать с указателем на массив указателей на строки.


CODE
typedef struct {

u8 QtyString;

u8 **pStr;

} MENU_PageText;





const u8 *MENU_TEXT_RU[] =

{

"выаопвылаопвыо",

"ывалдоплвыоапло",

"ывавыавыоапио"

};

..........

..........

const MENU_PageText PagesText[] =

{

{0x3,MENU_TEXT_EN},

{0x3, MENU_TEXT_DE},

{0x3,MENU_TEXT_IT},

{0x3, MENU_TEXT_RU}

};



Dog Pawlowa
Цитата(ISK2010 @ Aug 3 2011, 14:40) *
Лучше работать с указателем на массив указателей на строки.

Не факт, но инициализировать меню удобрее с помощью макросов, типа:

Код
STATE ( Abort                , "Aborted !"                , "Entnahme abgebrochen!"        ,"Остановлено!"                , CLR+STN+OLD+SSS+SLB    )
STATE ( Finish                , "Finished:"                , "Beendet:"                    ,"Закончено:"                , CLR+STN+OLD+SSS+SLB    )
011119xx
Проблема решается так:
Код
typedef struct
{
     int               x_numicons;                
     int               y_numicons;                
     int               iconnumber[10];            
} imenu_icons_t;

typedef struct
{
     imenu_icons_t      *menu_idle;                
     imenu_icons_t      *menu_active;          
     imenu_icons_t      *menu_icon;              
     char               *menu_text[10];            
} imenu_t;

imenu_icons_t main_icon = {1, 1, {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};

imenu_icons_t main_idle = {10, 1, {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}};

imenu_icons_t main_active = {10, 1, {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}};

const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};

void print(char *text)
{
    char c;

    while(c = *(text++))    
      {
           // Печать символа                        
      }
}

int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i;
     char **ptr = (char *)pmenu->menu_text[0];

     for(i = 0; i < entries; i++)
     {
    print(*(ptr + i));
     }

     return current;
}

unsigned char ic;

void main(void)
{
     ic = icon_menu(&mainmenu);
}
Палыч
Цитата(011119xx @ Aug 4 2011, 14:27) *
Проблема решается так

"Кривое" решение. Корректнее это сделать так:
Код
...
typedef struct
{
   imenu_icons_t    *menu_idle;                
   imenu_icons_t    *menu_active;          
   imenu_icons_t    *menu_icon;              
   char                     **menu_text;            
} imenu_t;
.....
const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};

.....
int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i;
     char **ptr = pmenu->menu_text;

....
}
....
011119xx
Keil ваш вариант не устраивает. А вот такой устраивает:
Код
...
typedef struct
{
   imenu_icons_t    *menu_idle;                
   imenu_icons_t    *menu_active;          
   imenu_icons_t    *menu_icon;              
   const char          **menu_text;            
} imenu_t;
.....
const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};

.....
int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i;
     const char **ptr = pmenu->menu_text;

     for(i = 0; i < entries; i++)
     {
         print((char *)(ptr + i));
     }
....
}
....
ar__systems
Цитата(011119xx @ Aug 4 2011, 06:27) *
Проблема решается так:

Подтверждаю, кривое, если не сказать кривейшее. Массив на 10 элементов, используется и инициализируется только один. Используется причем неправильно.

Код
char **ptr = (char *)pmenu->menu_text[0];

В этой строке вам ничего глаз не режет?
011119xx
Окончательный вариант принятый к использованию:

Код
...
typedef struct
{
   imenu_icons_t    *menu_idle;                
   imenu_icons_t    *menu_active;          
   imenu_icons_t    *menu_icon;              
   const char          **menu_text;            
} imenu_t;
.....
const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};

.....
int icon_menu(imenu_t *pmenu)
{
     unsigned char i, entries;

....
     for(i = 0; i < entries; i++)
     {
          print((char *)pmenu->menu_text[current]);
     }
....
}
....


XVR
Вот тут print((char *)pmenu->menu_text[current]); приведение типа лишнее. Можно просто написать print(pmenu->menu_text[current]);
sergeeff
Цитата(011119xx @ Aug 8 2011, 06:44) *
Окончательный вариант принятый к использованию:
Код
....
     for(i = 0; i < entries; i++)
     {
          print((char *)pmenu->menu_text[current]);
     }
....
}


Просто глаз радуется, глядя на цикл, в котором индекс никак не используется в теле.
011119xx
Цитата(sergeeff @ Aug 8 2011, 13:50) *
Просто глаз радуется, глядя на цикл, в котором индекс никак не используется в теле.

Так нормально?
Код
....
     for(i = 0; i < entries; i++)
     {
          print((char *)pmenu->menu_text[i]);
     }
....


Цитата(XVR @ Aug 8 2011, 13:46) *
Можно просто написать print(pmenu->menu_text[current]);

Keil на такое ругается так как print объявлена:
void print(char *str);
sergeeff
Цитата(011119xx @ Aug 8 2011, 12:33) *
Так нормально?
Код
....
     for(i = 0; i < entries; i++)
     {
          print((char *)pmenu->menu_text[i]);
     }
....



Keil на такое ругается так как print объявлена:
void print(char *str);



Вам лучше знать, нормально это или нет. Вы же автор кода.


Объявите функцию print:

Код
void print(const char *str);


Тогда она будет без проблем вызываться с const и не const фактическими переменными.
Палыч
Цитата(011119xx @ Aug 8 2011, 12:33) *
Keil на такое ругается
Сообщение транслятора об ошибке приведите
sergeeff
Как пить дать человек компилирует С++`ом. Тогда print(const char *a) и print(char *a) - суть разные функции. А вот указатель на const char * из char * С++ компилятор приводит автоматом. Посему и рекомендовал объявить print(const char *a) и не парится в будущем с ручным приведением.
011119xx
Цитата(sergeeff @ Aug 8 2011, 16:14) *
Как пить дать человек компилирует С++`ом. Тогда print(const char *a) и print(char *a) - суть разные функции. А вот указатель на const char * из char * С++ компилятор приводит автоматом. Посему и рекомендовал объявить print(const char *a) и не парится в будущем с ручным приведением.

Нет не С++ компилятор.
ar__systems
Цитата(sergeeff @ Aug 8 2011, 06:14) *
Как пить дать человек компилирует С++`ом. Тогда print(const char *a) и print(char *a) - суть разные функции.


Дело не в этом, а в том, что в char * нельзя передавать const char * качестве аргумента.
sergeeff
Цитата(ar__systems @ Aug 8 2011, 15:55) *
Дело не в этом, а в том, что в char * нельзя передавать const char * качестве аргумента.


Это в Канаде, наверное нельзя (может религия не позволяет), а в С можно. Себе тестик в Visual Studio или чем-то другом напишите - увидите.
ar__systems
Цитата(sergeeff @ Aug 8 2011, 08:17) *
Это в Канаде, наверное нельзя (может религия не позволяет), а в С можно. Себе тестик в Visual Studio или чем-то другом напишите - увидите.

Да, действительно. А нафига тогда вообще в С слово const?
Палыч
Цитата(ar__systems @ Aug 8 2011, 17:07) *
А нафига тогда вообще в С слово const?
Указать транслятору на неизменяемые переменные, массивы, структуры... Некоторые трансляторы изымают их из ОЗУ.
XVR
Цитата(sergeeff @ Aug 8 2011, 16:17) *
Это в Канаде, наверное нельзя (может религия не позволяет), а в С можно. Себе тестик в Visual Studio или чем-то другом напишите - увидите.

Написал:
Код
char* func(char* p)
{
return p;
}

const char *gl;

char* func2()
{
return func(gl);
}

Цитата
C:\!t>gcc-4.exe -c t.c
t.c: In function 'func2':
t.c:10: warning: passing argument 1 of 'func' discards qualifiers from pointer target type

Так что и в С не очень можно (но если очень хочется, то можно - это все же warning, а не error)
sergeeff
Скажем спасибо людям, написавшим gcc, что оповещают warning'ом! Кстати хороший пример в тему С/С++, что зачем и почему.
011119xx
Цитата(sergeeff @ Aug 8 2011, 18:17) *
Это в Канаде, наверное нельзя (может религия не позволяет), а в С можно. Себе тестик в Visual Studio или чем-то другом напишите - увидите.

Вы Keil к Visual Studio подключили? Если так, то научите и меня пожалуйста. А по сути религии могу сказать так: на один и тот же весьма простой исходный текст Keil выдает разные сообщения об ошибках и предупреждениях, если компилировать под С51 и ARM. Скажем, если под С51 его все устраивает, то под ARM уже находит ошибки.
Genadi Zawidowski
Код
typedef struct
{
     int               x_numicons;                
     int               y_numicons;                
     int               iconnumber[10];            
} imenu_icons_t;

typedef const char *imenu_text_t[10];

typedef struct
{
     imenu_icons_t      *menu_idle;                
     imenu_icons_t      *menu_active;          
     imenu_icons_t      *menu_icon;              
     imenu_text_t        *menu_text;            
} imenu_t;

imenu_icons_t main_icon = {1, 1, {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};

imenu_icons_t main_idle = {10, 1, {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}};

imenu_icons_t main_active = {10, 1, {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}};

const char * main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};

int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i;
     char *ptr;

//     Â ôóíêöèè ïîêàçàíî íå âñå, ïîýòîìó ïóñòü íå ñìóùàåò åå áåññìûñëåííîñòü

     for(i = 0; i < entries; i++)
     {
           ptr = (char *)pmenu->menu_text[i];
     }

     return current;
}

unsigned char ic;

void xmain(void)
{
     ic = icon_menu(&mainmenu);
}
sergeeff
Цитата(011119xx @ Aug 9 2011, 06:52) *
Вы Keil к Visual Studio подключили? Если так, то научите и меня пожалуйста. А по сути религии могу сказать так: на один и тот же весьма простой исходный текст Keil выдает разные сообщения об ошибках и предупреждениях, если компилировать под С51 и ARM. Скажем, если под С51 его все устраивает, то под ARM уже находит ошибки.


1. Когда я упоминал Visual studio, соответственно речь шла о семействе компиляторов Microsoft.
2. Никто не запрещает вам открыть новый проект в Visual studio, основанный на make, и вообще делать все что хочешь (в смысле вызывать любые компиляторы, линкеры и т.п.). Вот с синхронизацией ошибок в output-окне и editor'e будут проблемы, это да.
3. Если хочется, то можно загрузить бесплатно пакет Visual Studio 2008/2010 SDK и наваять оболочку под себя.
011119xx
Снова возвращаюсь к данной теме, так как потребовалось усложнить интерфейс введением поддержки 2-х языков. Соответственно, код используемый ранее требует доработки:
Код
...
typedef struct
{
   imenu_icons_t    *menu_idle;                
   imenu_icons_t    *menu_active;          
   imenu_icons_t    *menu_icon;              
   const char          **menu_text;            
} imenu_t;
.....
const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};

.....
int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i;
     const char **ptr = pmenu->menu_text;

     for(i = 0; i < entries; i++)
     {
         print((char *)(ptr + i));
     }
....
}
....

В первую очередь это:
Код
const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};

меняю на это:
Код
const char *main_text[2][10] = {{"STR1_EN", "STR2_EN", "STR3_EN", "STR4_EN", "STR5_EN", "STR6_EN", "STR7_EN", "STR8_EN", "STR9_EN", "STR10_EN"},
{"STR1_RU", "STR2_RU", "STR3_RU", "STR4_RU", "STR5_RU", "STR6_RU", "STR7_RU", "STR8_RU", "STR9_RU", "STR10_RU"}};

А далее в общем-то запутался. По идее вот это:
Код
typedef struct
{
   imenu_icons_t    *menu_idle;                
   imenu_icons_t    *menu_active;          
   imenu_icons_t    *menu_icon;              
   const char          **menu_text;            
} imenu_t;

надо тоже менять, правда не пойму как. Функцию, использующую строки меняю на:
Код
int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i, language;
     const char **ptr = pmenu->menu_text;     //нужно править и как-то использовать language

     for(i = 0; i < entries; i++)
     {
         print((char *)(ptr + i));     //нужно править и как-то использовать language
     }
....
}

Прошу подсказки специалистов как правильно сделать.
MrYuran
Цитата(sergeeff @ Aug 9 2011, 17:14) *
2. Никто не запрещает вам открыть новый проект в Visual studio, основанный на make, и вообще делать все что хочешь (в смысле вызывать любые компиляторы, линкеры и т.п.). Вот с синхронизацией ошибок в output-окне и editor'e будут проблемы, это да.

Проблемы с форматом вывода решаемы
Однако, поработав в этой вашей студии, сакрального смысла не нашел.
Это так, в порядке оффтопа.


А насчет предупреждения - это просто несовпадение типов. И это не ошибка, а именно предупреждение на всякий случай, чтобы заострить внимание.
Вот если объявленную константой строку попытаться изменить - тогда будет уже явная ошибка.

Цитата(011119xx @ Jun 8 2012, 10:34) *
Прошу подсказки специалистов как правильно сделать.

Сделать два отдельных массива адресов сообщений, а в функцию передавать адрес нужного (в зависимости от языка) и номер сообщения.

Если я правильно понял задачу.
011119xx
Цитата(MrYuran @ Jun 8 2012, 11:53) *
Сделать два отдельных массива адресов сообщений, а в функцию передавать адрес нужного (в зависимости от языка) и номер сообщения.

Такой вариант имеет право на жизнь, но мне не подходит. Адрес нужного (в зависимости от языка) и номер сообщения нужно определять в функции
Код
int icon_menu(imenu_t *pmenu)
.
И я знаю, что сделать это можно, но пока не могу сообразить.
011119xx
Работает вот так:
Код
int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i, language = 1;
     const char **ptr = pmenu->menu_text;    

     for(i = 0; i < entries; i++)
     {
         print((char *)(*(ptr + i + language * entries)));    
     }
....
}

но хотелось бы избавиться от локального указателя const char **ptr

Немного криво, но работает так:
Код
int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i, language = 1;

     for(i = 0; i < entries; i++)
     {
         print((char *)(*(&pmenu->menu_text[i + language * entries])));    
     }
....
}
XVR
Код
typedef struct
{
   imenu_icons_t    *menu_idle;                
   imenu_icons_t    *menu_active;          
   imenu_icons_t    *menu_icon;              
   const char          *(*menu_text)[10];            
} imenu_t;

const char *main_text[2][10] = {{"STR1_EN", "STR2_EN", "STR3_EN", "STR4_EN", "STR5_EN", "STR6_EN", "STR7_EN", "STR8_EN", "STR9_EN", "STR10_EN"},
{"STR1_RU", "STR2_RU", "STR3_RU", "STR4_RU", "STR5_RU", "STR6_RU", "STR7_RU", "STR8_RU", "STR9_RU", "STR10_RU"}};

imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};

void print(const char*);

int icon_menu(imenu_t *pmenu)
{
     unsigned char current = 0, i, language;
     const char **ptr = pmenu->menu_text[language];

     for(i = 0; i < entries; i++)
     {
         print(ptr[i]);
     }
....
}



Или сразу -
Код
print(pmenu->menu_text[language][i]);

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.