Данные из массива всегда разные. Почему?

mishgan
Offline
Зарегистрирован: 25.04.2014

Делаю небольшой проект по управлению пивоварней. Рецепты хранятся на sd карте в таком виде -

3,IPA,62,72,82,3,3,3,8,3,2,5,7;

3,STAUT,32,43,62,10,25,30,60,3,60,90,95;

5,BITTER,30,40,50,60,70,10,20,30,40,50,60,3,60,90,95;

3,PORTER,32,45,72,10,25,30,30,2,10,20;

.....

А так я его заношу в массив


char *recepies[30][30];
void setup()
{
  Serial.begin(9600);
....
SD_recepies() ;
//проверка №1
for (int j=0; j <10 ; j++) {
  Serial.print(recepies[j][0]); Serial.print("-") ;Serial.print(recepies[j][1]);Serial.print("-") ;Serial.println(recepies[j][2]);
}
}
void SD_recepies() {
String stringOne = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,;";
int q=0;
int t=0;
int h=0;
char symbol2 = 0;
char array[10];
File configFile = SD.open("recepies.txt");
if (configFile) {
      while  (configFile.available())  {
       symbol2 = configFile.read();
    if (stringOne.indexOf(symbol2)!=-1) {
      if (symbol2==';' ) {t++; recepies[q][t]=array;  q++; t=0; h=0 ; kol_receptov++;  memset (array, 0, sizeof(array));  }
      else {
        if (symbol2==',') {recepies[q][t]=array; h=0; t++;  memset (array, 0, sizeof(array)); }
        else  {array[h]=symbol2; h++;}
      }
    }
  
      delay(1);
    }
    configFile.close();
}
//проверка №2
  for (int j=0; j <10 ; j++) {
  Serial.print(recepies[j][0]); Serial.print("-") ;Serial.print(recepies[j][1]);Serial.print("-") ;Serial.println(recepies[j][2]);
}
}

Делаю 2 проверки. Проверка №1 выдает иероглифы, 2-я выдает только знаки "-".

если добавить в строчки 

 if (symbol2==';' ) {t++; recepies[q][t]=array;  q++; t=0; h=0 ; kol_receptov++;  memset (array, 0, sizeof(array));  } ...
if (symbol2==',') {recepies[q][t]=array; h=0; t++;  memset (array, 0, sizeof(array)); }

после recepies[q][t]=array; следующее Serial.println(recepies[q][t]); то выводит все как надо.

Всю голову себе сломал..... Подскажите где я не то делаю...

maksim
Offline
Зарегистрирован: 12.02.2012

mishgan пишет:

после recepies[q][t]=array; следующее Serial.println(recepies[q][t]); то выводит все как надо.

Что выводит как надо? Что вы вообще пытаетесь сделать в этой строке recepies[q][t]=array;

mishgan
Offline
Зарегистрирован: 25.04.2014

Выводит данные из массива.  Т.е.

3

IPA

62

72

82

3

3

3

и т.д.

Перебираю символы из файла. Складываю символы до появления запятой или ";" . После эти объедененные данные  записывается в массив recepies где q- номер строки t-позиция в строке.

maksim
Offline
Зарегистрирован: 12.02.2012

mishgan пишет:

После эти объедененные данные  записывается в массив recepies где q- номер строки t-позиция в строке.

Вам так только кажется.

Во-первых, научитесь форматировать код, для этого есть сочитание клавиш Ctrl+T.

Во-вторых, вам нужно изучить, что такое массив, что такое строки в си и как ими пользоваться.

Ну а в-третих, судя по коду вы выполняя это recepies[q][t]=array; пытаетесь запихнуть строку в один символ, на самом же деле передаете указатель (адрес) массива array элементу массива recepies[q][t]. И да, сразу после этого вы читаете recepies[q][t] по этому адресу находится массив array, но как только вы его переписываете новыми данными по этому адресу находятся уже новые данные, а когда вы выходите из функции SD_recepies(), то по этому адресу лежит "мусор".

Что бы присвоить данные одного массива другому существует, например, функции memcpy или strcpy. Но даже если вы это сделаете, так как я уже вам написал выше, что вы пытаетесь сделать, у вас в массиве recepies[q][t] будет сохраняться только первый символ массива array.

И в-четвертых, для чего вы вообще это делаете? Ведь вам же нужны числа как переменные, а не как строки, так вот лучше создайте массив переменных числового типа (например int) и сразу преобразовывайте строки в числа и складывайте в этот массив.

mishgan
Offline
Зарегистрирован: 25.04.2014

Огромное спасибо... Буду изучать матчасть.

mishgan
Offline
Зарегистрирован: 25.04.2014

Проштудировал всю инфу по массивам и строкам. Изменил код на следующий. Но опять не хочет работать так как я хочу


char  *recname[30];
int   recpara[30][20];
.....
 char array[100];
  char *buffer;
  char *p;
....
 if (symbol2==';') {
          array[h]='\0';
          for( buffer = strtok_r(array, ",", &p); buffer; buffer = strtok_r(NULL, ",", &p) ){
            if (t==0) {
              recname[q]=buffer;
            }
            else      {
              recpara[q][t]=atoi(buffer);
            }
            t++;
          }
          t=0;
          q++;
          h=0;
          kol_receptov++;
          memset(array, 0, sizeof(array));
        }
        else {
          array[h]=symbol2; 
          h++;
        }

 

массив recpara вне функции доступен. массив recname чудит...  

Код

 for (int j=0; j <10 ; j++) {
   Serial.print(recname[j]); Serial.println(recpara[j][2]);
   }

выводит данные только из recpara

maksim
Offline
Зарегистрирован: 12.02.2012

mishgan пишет:

Проштудировал всю инфу по массивам и строкам.

Плохо проштудировали. Изучайте что такое строки в си.

mishgan пишет:

массив recpara вне функции доступен. массив recname чудит...  

Это не массив ,это вы чудите - что вы пытаетсь сделать обьявляя массив указателей char *recname[30]; и указатели char *buffer; char *p; никак их не инициализируя?

maksim
Offline
Зарегистрирован: 12.02.2012
char recname[30][15];
int recpara[30][20];


void Load_receipts() {
  File configFile = SD.open("recepies.txt");
  if (configFile) 
  {
    char buff[15];
    byte rec = 0, par = 0, c = 0;
    while(configFile.available())
    {
      char symb = configFile.read();
      if(symb >= 32)
      {
        if(symb == ',' || symb == ';')
        {
          buff[c] = '\0';
          c = 0;
          if(par == 0) strcpy(recname[rec], buff);
          else recpara[rec][par-1] = atoi(buff);
          par++;

          if(symb == ';')
          {
            par = 0;
            rec++;
          }
        }
        else buff[c++] = symb;
      }
    }
  }
}

Первым в строке должно идти название рецепта.

mishgan
Offline
Зарегистрирован: 25.04.2014

Все отлично работает. Спасибо за советы и подсказки

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Все отлично работает.
.......а пЫво-то варится уже ? :)

mishgan
Offline
Зарегистрирован: 25.04.2014

пока электронику не использую.... на газу все делаю....