Перейти к содержимому

Фото
- - - - -

Создание массива на основании анализа строки. С++

C/C++

Лучший Ответ Володька, 19 марта 2015 - 14:00

Да я уже сам понял, что это ничего не меняет.

 

Попробуй для проверки уменьшить массив Data хотя бы до unsigned char data[7][8].

Возможно, что компилятору такой большой массив в контроллер не разместить, странно что ошибку не выдаёт, но всё же.

Перейти к полному сообщению


  • Вы не можете создать новую тему
  • Please log in to reply
31 ответов в этой теме

#1 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 20:14

Нужно создать массив данных to_display на основании анализа строки  phrase.

каждая буква добавляет в массив 8 значений. Все разные и зависят от буквы.

таблица соответствий хранится в массиве data.

 

Вроде что-то изобразил, но не работает. Массив, похоже не создаётся или содержит нули.

В чём беда?

 

[spoiler='Код программы.']
char phrase[ ] = "ABCDEFG";

unsigned char to_display[sizeof(phrase) * 8];


void setup()
{

  unsigned char data[256][8] =
  {
    {124, 254, 211, 17, 17, 255, 254, 0}, //1-a
    {255, 255, 18, 33, 121, 207, 134, 0}, //2-r
    {255, 255, 130, 129, 193, 127, 30, 0},// 3-d
    {121, 255, 131, 128, 128, 255, 127, 0},
    {130, 129, 157, 255, 227, 129, 65, 0},
    {127, 255, 134, 8, 49, 255, 254, 0},
    {120, 254, 195, 129, 195, 254, 120, 0}
  };



  for (int i = 0; i < sizeof(phrase) - 1; i++)
  {
    char a = phrase[i];

    switch (a) {
      case 'A':       
        for (int j = 0; j < 8; j++)
          to_display[i * 8 + j] = data[5][j];
          break;
      //
      case 'B':
        for (int j = 0; j < 8; j++)
          to_display[i * 8 + j] = data[1][j];
        break;
      //
      case 'C':
        for (int j = 0; j < 8; j++)
          to_display[i * 8 + j] = data[2][j];
        break;
      //
      case 'D':
        for (int j = 0; j < 8; j++)
          to_display[i * 8 + j] = data[3][j];
        break;
      //
      case 'E':
        for (int j = 0; j < 8; j++)
          to_display[i * 8 + j] = data[4][j];
        break;
      //
      case 'F':
        for (int j = 0; j < 8; j++)
          to_display[i * 8 + j] = data[5][j];
        break;
      //
      case 'G':
        for (int j = 0; j < 8; j++)
          to_display[i * 8 + j] = data[6][j];
        break;
    }

  }

} 
[/spoiler]
  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#2 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 20:44

Вроде что-то изобразил, но не работает. Массив, похоже не создаётся или содержит нули.

 

Откуда это следует?


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#3 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 20:49

Если 

 

Откуда это следует?

 

Если создать этот массив инициализацией при старте программы и закомментировать все строки

to_display[i * 8 + j] = data[3][j]; 

то все работает.  Сами условия case тоже работают, ставил на их результат другое действие. 

 

Остаётся только обработка массива.  Даже если изначально массив не пустой, то обработка его портит. Ничего не выводится


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#4 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 20:54

В MSVC заполняются 56 ячеек как и должно быть.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#5 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 21:04

Тут полный код. где ещё можно накосячить?

 

[spoiler='Код.']
#include "LedControl.h" //  нужна данная библиотека
LedControl lc = LedControl(12, 11, 10); // подключенные пины


int p = 40;
char phrase[ ] = "ABCDEFG";


unsigned char to_display[sizeof(phrase)*8];





void scroll()
{
  for (int i = 0; i < sizeof(to_display) - 8; i++)
  {
    for (int j = 0; j < 8; j++)
      lc.setRow(0, j, to_display[i + j]);
    delay(p);
  }
}





void setup()
{
  lc.shutdown(0, false); // выключите энергосбережения, вкл. дисплей
  lc.setIntensity(0, 0); // Устанавливаем яркость (0~15 возможные значения)
  lc.clearDisplay(0);// очистить экран


  unsigned char data[256][8] =
  {
    {124, 254, 211, 17, 17, 255, 254, 0}, //1-a
    {255, 255, 18, 33, 121, 207, 134, 0}, //2-r
    {255, 255, 130, 129, 193, 127, 30, 0},// 3-d
    {121, 255, 131, 128, 128, 255, 127, 0},
    {130, 129, 157, 255, 227, 129, 65, 0},
    {127, 255, 134, 8, 49, 255, 254, 0},
    {120, 254, 195, 129, 195, 254, 120, 0}
  };



  for (int i = 0; i < sizeof(phrase) - 1; i++)
  {
    char a = phrase[i];

    switch (a) {
      case 'A':
        for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j] = data[5][j];
          break;
        }
      case 'B':
        for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j] = data[1][j];
        break;
        }
      //
      case 'C':
        for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j] = data[2][j];
        }
        break;
      //
      case 'D':
        for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j] = data[3][j];
        }
        break;
      //
      case 'E':
        for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j] = data[4][j];
        break;
        }
      //
      case 'F':
        for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j] = data[5][j];
        }
        break;
      //
      case 'G':
        for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j] = data[6][j];
        }
        break;
    }
  }

}





void loop()
{

  scroll();
} 
[/spoiler]
  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#6 Sergio

Sergio
  • Постоялец
  • 3 051 сообщений

Отправлено 18 марта 2015 - 21:12

строка

unsigned char to_display[sizeof(phrase) * 8];

неправильная. g++ создает массив нулевого размера


  • 0

#7 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 21:15

строка

unsigned char to_display[sizeof(phrase) * 8];

неправильная. g++ создает массив нулевого размера

 

Можно поподробнее? где там g++ и почему нулевой размер, когда явно указана зависимость от длины строки? Как исправить и что?

 

 

Заменил на такую... ничего не получилось.

unsigned char to_display[56]={1,2,3,4,5,6,7,8,9,0};


Сообщение изменено: BiHiTRiLL (18 марта 2015 - 21:23 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#8 Sergio

Sergio
  • Постоялец
  • 3 051 сообщений

Отправлено 18 марта 2015 - 21:37

 

Можно поподробнее? где там g++ и почему нулевой размер, когда явно указана зависимость от длины строки? Как исправить и что?

 

 

Заменил на такую... ничего не получилось.

unsigned char to_display[56]={1,2,3,4,5,6,7,8,9,0};

 

Нулевой размер показывает отладчик gdb.

Правильней вроде бы как то так

     int dispsize = sizeof(phrase) * 8;
     unsigned char * to_display = new unsigned char [dispsize];

Давно я ничего не писал на C и C++, не помню уж тонкостей.


  • 0

#9 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 21:54

Нулевой размер показывает отладчик gdb.

Правильней вроде бы как то так

     int dispsize = sizeof(phrase) * 8;
     unsigned char * to_display = new unsigned char [dispsize];

Давно я ничего не писал на C и C++, не помню уж тонкостей.

Он же статически создал и строку, и выходной массив, все на этапе компиляции еще определится.

В MSVC все отрабатывает как надо.

BiHiTRiLL, ты каким компилятором пользуешься?

 

когда явно указана зависимость от длины строки? Как исправить и что?

Тут не совсем от длины строки, от размера массива. Просто в данном случае эти понятия совпали.

Попробуй выведи sizeof(phrase), посмотри, правильно ли он определил его.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#10 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 21:54

Zero

 



Он же статически создал и строку, и выходной массив, все на этапе компиляции еще определится.

В MSVC все отрабатывает как надо.

BiHiTRiLL, ты каким компилятором пользуешься?

 

 Это среда разработки для arduino - ARDUINO IDE


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#11 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 21:58

Тогда, смотри sizeof'ы для начала. И входного и выходного массива.


 

Заменил на такую... ничего не получилось.

Что значит "ничего не получилось"? Запустил программу - потух свет во всем городе?


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#12 Sergio

Sergio
  • Постоялец
  • 3 051 сообщений

Отправлено 18 марта 2015 - 21:58

Он же статически создал и строку, и выходной массив, все на этапе компиляции еще определится.

 

Да нее, при таком объявлении массива допускается только константа в качестве размера.

Хотя, может я отстал от жизни, может быть по C++14 и можно... Не знаю.

Но вообще это классическая ошибка.

Ну а MS всегда отличались своебразным подходом к стандартам.

 


  • 0

#13 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 22:11

Да нее, при таком объявлении массива допускается только константа в качестве размера.

Хотя, может я отстал от жизни, может быть по C++14 и можно... Не знаю.

Но вообще это классическая ошибка.

Ну а MS всегда отличались своебразным подходом к стандартам.

Я тоже сначала так подумал, но потом проверил в MSVC 2010, все работает.

 

Да и sizeof статического массива - константа, которую можно определить на этапе компиляции.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#14 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 22:13

Тогда, смотри sizeof'ы для начала. И входного и выходного массива.


Что значит "ничего не получилось"? Запустил программу - потух свет во всем городе?

 

Это значит что на матрицу ничего не выводится. она не горит. при прочих равных.


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#15 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 22:14

Tiny C Compiler тоже рад:

 

#include <stdio.h>

int main(int argc, char* argv[])
{
    char phrase[ ] = "ABCDEFG";
 
    unsigned char to_display[sizeof(phrase) * 8];

    int i = sizeof(phrase);
    int i2 = sizeof(to_display);
    printf("phrase size: %d, to_display size: %d\r\n", i, i2);

    return 0;
}

 

Вывод: 8 и 64.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#16 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 22:17

Опечатался и вылез странный глюк:

 

Так ничего не работает. Хотя вроде правильно.

    case 'A':
      for (int j=0; j<8; j++)
      {
        to_display[i*8+j]=data[0][j];
      }
      break;

А вот так: работает но криво, заполняет только одно значение и вываливается по break. Но массив не обнуляется. результат виден

    case 'A':
      for (int j=0; j<8; j++)
      {
        to_display[i*8+j]=data[0][j];
    break;
      }


     

Сообщение изменено: BiHiTRiLL (18 марта 2015 - 22:19 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#17 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 22:22

Sergio, GCC (4,8,2) отлично переварил и дал тот же результат, что и MSVC и TCC: 8 и 64.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#18 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 22:25

Дядьки, я не могу использовать другой компилятор. мне микроконтроллер нужно запрограммировать. Хочется понять где тут собака зарыта.

 

Может можно как-то по другому это закодить? 

 

Поменял на IF - результат прежний. 


if (a='A')
{
      for (int j=0; j<8; j++)
      {
        to_display[i*8+j]=data[0][j];
      }
}

Сообщение изменено: BiHiTRiLL (18 марта 2015 - 22:31 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#19 Sergio

Sergio
  • Постоялец
  • 3 051 сообщений

Отправлено 18 марта 2015 - 22:26

Sergio, GCC (4,8,2) отлично переварил и дал тот же результат, что и MSVC и TCC: 8 и 64.

Да, с gcc твой пример работает. А вот изначальный пример автора почему то нет. Может это я  сам где-то опечатался.


Сообщение изменено: Sergio (18 марта 2015 - 22:30 )

  • 0

#20 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 22:36

Sergio, sizeof - константа, как ни крути.

Вот хочешь ты массив байтов на 10 интов определить, так и будет [sizeof(int) * 10], здесь то же.

 

 

А вот так: работает но криво, заполняет только одно значение и вываливается по break. Но массив не обнуляется. результат виден

Что значит "не обнуляется"? У тебя там изначально мусор может быть вообще. Если заполняется 0ми, значит, data[0][j] не туда лезет?

BiHiTRiLL, а зачем ты определил 256 строк, если используешь только 7?

 

Дядьки, я не могу использовать другой компилятор. мне микроконтроллер нужно запрограммировать. Хочется понять где тут собака зарыта.

 

 

Язык тот же, так что неважно.

Поменял на IF - результат прежний. 

if (a='A')
{
    

Это уже EPIC FAIL.

BiHiTRiLL, ты размеры созданных массивов можешь проверить?


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#21 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 22:38

Sergio

 

Что значит "не обнуляется"?

 

Это значит что я вижу на экране значение первого байта. из data[0] [0]

 

 

а зачем ты определил 256 строк, если используешь только 7?

 

 

Это знакогенератор. для каждой буквы будет свой набор чисел в массиве.


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#22 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 22:39

Еще: sizeof(phrase) учитывает скрытый ноль.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#23 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 18 марта 2015 - 22:47

Еще: sizeof(phrase) учитывает скрытый ноль.

это я знаю. просто пока с остальным непонятно, до этого руки не дошли еще.


ты размеры созданных массивов можешь проверить?

 

 

если только косвенно. Отладчика тут нету.


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#24 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 18 марта 2015 - 22:47

В tcc код из первого поста тоже нормально сработал.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#25 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 12:43

Следуя логике, получается что компилятор криво работает? Но я же не один кто такое использует...

 

Zero, при работе кода в массив заносятся правильные данные? Из data, от нулевого значения до седьмого?

 

 

Вот вчера сделал для наглядности. Объявляю массив так:

byte to_display[(sizeof(phrase) - 1) * 8] = {
  1, 1, 1, 1, 1, 1, 1, 1,
  2, 2, 2, 2, 2, 2, 2, 2,
  4, 4, 4, 4, 4, 4, 4, 4,
  8, 8, 8, 8, 8, 8, 8, 8,
  16, 16, 16, 16, 16, 16, 16, 16,
  32, 32, 32, 32, 32, 32, 32, 32,
  64, 64, 64, 64, 64, 64, 64, 64,
  128, 128, 128, 128, 128, 128, 128
};

при этом в секции switch комментирую все обращения к массиву:

switch (a) {
      //
      case 'A':
          for (int j = 0; j < 8; j++)
            //to_display[i * 8 + j]  = data[0][j];
          break;
      //
      case 'B':
        for (int j = 0; j < 8; j++)
          // to_display[i * 8 + j] = data[1][j];
          break;

      //
      case 'C':
        for (int j = 0; j < 8; j++)
          // to_display[i * 8 + j]  = data[2][j];
          break;

      //
      case 'D':
        for (int j = 0; j < 8; j++)
          // to_display[i * 8 + j] = data[3][j];
          break;

      //
      case 'E':
        for (int j = 0; j < 8; j++)
          // to_display[i * 8 + j] = data[4][j];
          break;

      //
      case 'F':
        for (int j = 0; j < 8; j++)
          // to_display[i * 8 + j] = data[5][j];
          break;

      //
      case 'G':
        for (int j = 0; j < 8; j++)
          // to_display[i * 8 + j] = data[6][j];
          break;
    }

На экране, как и положено, бегут горизонтальные полосы.  Видео.

 

Стоит только в любом блоке case раскомментировать строку:

// to_display[i * 8 + j] = data[6][j];

И экран становится пустым. 


Сообщение изменено: BiHiTRiLL (19 марта 2015 - 12:45 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#26 Володька

Володька
  • Пользователь
  • 476 сообщений
  • Откуда:Силламяэ

Отправлено 19 марта 2015 - 13:46

Попробуй может переменную j заранее инициализировать. То есть:

char a = phrase[i];
int j=0;
switch (a) {
    case 'A':
        for (j = 0; j <= 8; j++) {
            to_display[i * 8 + j] = data[0][j];
        }
        break;

и т.д.

Ну и все break; естественно за цикл for вынеси.

 

Хотя не.. и так вроде всё норм.


Сообщение изменено: Володька (19 марта 2015 - 13:54 )

  • 0

#27 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 13:54

Еще несколько нюансов....

Глюк похоже  в обращении к data.

 

делаю так:

  int s;     
.
.
.

       case 'A':
          for (int j = 0; j < 8; j++)
          {
            //to_display[i * 8 + j]  == data[0][j];

            Serial.print("data "); 
            s = data[0][j]; 
            //Serial.println(s, DEC); 
          } 
          break;

Все работает. 

 

 

А если раскомментировать 

//Serial.println(s, DEC);

То экран опять пустой.


Попробуй может переменную j заранее инициализировать. 

Не помогло. Изменений нет.


Сообщение изменено: BiHiTRiLL (19 марта 2015 - 13:57 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#28 Володька

Володька
  • Пользователь
  • 476 сообщений
  • Откуда:Силламяэ

Отправлено 19 марта 2015 - 14:00   Лучший Ответ

Да я уже сам понял, что это ничего не меняет.

 

Попробуй для проверки уменьшить массив Data хотя бы до unsigned char data[7][8].

Возможно, что компилятору такой большой массив в контроллер не разместить, странно что ошибку не выдаёт, но всё же.


  • 1

#29 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 14:07

Володька,

ты гений!!! Этот аццкий сотона arduino  не хавает такой большой массив!!!

 

Побежали буковки!!!

Сейчас попробую запихнуть весь знакогенератор. может хватит памяти.


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#30 Володька

Володька
  • Пользователь
  • 476 сообщений
  • Откуда:Силламяэ

Отправлено 19 марта 2015 - 14:16

Всё оказалось довольно банально, странно конечно, что arduino ide ошибку по этому поводу вообще никакую не выдаёт.

Памяти в МК может хватать сполна, и я не знаю как у Atmel, но у Microchip что бы объявить большой массив на несколько банок памяти, надо с бубном поплясать.

Если не хочешь заморачиваться, то проще определить при каком максимальном размере массива нет глюков, и объявить таких несколько штук.


Сообщение изменено: Володька (19 марта 2015 - 14:19 )

  • 0