Возвращение Си-строки Функцией

Newby
Offline
Зарегистрирован: 22.03.2014

Доброго дня, есть простая задача : в одной из локальных функций нужно формировать си-строку (массив char) из комбинации префикса и номера элемента.

Сделал такой код, который работает:



char pref[]="ledbtn_";  //префикс, numbutton - глобальная=5
   int sz=sizeof(numbutton)*(sizeof (pref)+sizeof(numbutton)); //рассчитываем размер итоговой строки
  char string[sz]=""; 

  for (int i=0; i<numbutton; ++i){
    char num[sizeof(numbutton)]; itoa(i,num,DEC);
   strcat(string,pref);
   strcat(string,num);
   if(i<numbutton-1){ //после последнего элемента запятая не нужна
   strcat(string,",");
   }
   
  }
  Serial.println(string); // вывод: ledbtn_0,ledbtn_1,ledbtn_2,ledbtn_3,ledbtn_4

Но когда я пытаюсь вынести этот кусок в отдельную функцию - ничего не получается. постоянно жалуется на "invalid conversion from 'char' to 'const char*' " 

Идея сделать так:

 //вызов функции
char pref[]="ledbtn_"; 

char string[]=CharStrPrefixNum(numbutton, pref);

char CharStrPrefixNum(int imax, char *prefix){

int sz=sizeof(imax)*(sizeof (prefix)+sizeof(imax));
  char string[sz]="";

  for (int i=0; i<imax; ++i){
    char num[sizeof(imax)]; itoa(i,num,DEC);
   strcat(string,prefix);
   strcat(string,num);
   if(i<imax-1){
   strcat(string,",");
   }
   
  }
 // Serial.println(string);

  return string;

}


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

const char *str=CharStrPrefixNum(numbutton, pref);

char* CharStrPrefixNum (int imax, char *prefix){
  int sz=sizeof(imax)*(sizeof (prefix)+sizeof(imax));
  char string[sz]="";
  Serial.println(sizeof(string));
  for (int i=0; i<imax; ++i){
    char num[sizeof(imax)]; itoa(i,num,DEC);
   strcat(string,prefix);
   strcat(string,num);
   if(i<imax-1){
   strcat(string,",");
   }
   
  }
  Serial.println(string);
  return string;
}

Как правильно делать в данном случае?

rkit
Offline
Зарегистрирован: 23.11.2016

Изучить тему указателей, чтобы не работать наугад?

Newby
Offline
Зарегистрирован: 22.03.2014

rkit пишет:

Изучить тему указателей, чтобы не работать наугад?

слишком сложная тема чтобы её полностью изучить. Я гуглил темы "как передавать массив из функции" - но путного особо ничего не нашел. Либо предлагают применять malloc() - а это ведет к фрагментации памяти и сложно отлавливаемым багам - лучше этими функицями не пользоваться в принципе. темболее, что не зная размер массива который я получу от функции, я не смогу очистить память.

Либо управление внешней переменной через указатель. да, это работает, но тогда нужно задавать размер итогового массива вне функции - а он может менятся каждый раз, функция для того и нужна, чтобы не писать эту строку каждый раз.

 

rkit
Offline
Зарегистрирован: 23.11.2016

Newby пишет:

слишком сложная тема чтобы её полностью изучить

Тогда программирование это не твое и тебе нужно писать ТЗ в платный раздел.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

я резиновые данные возвращал через стек (но я не настоящий сталевар)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

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

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

И const на char не может быть т к переменная меняется.

b707
Offline
Зарегистрирован: 26.05.2017

Newby пишет:

слишком сложная тема чтобы её полностью изучить.

не пугайтесь, не такая и сложная. Указатель - это адрес переменной в памяти, вот и все :)

Цитата:
Либо предлагают применять malloc() ...   либо управление внешней переменной через указатель

а других вариантов, собственно, и нет. Либо заранее выделяете кусок памяти с  запасом, чтобы в него вошла любая из используемых строк, либо пользуетесь malloc. Беспокоится о размере массива в случае очистки не надо, это один из немногих примеров в С++, когда система действует автоматически.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

В WinAPI  раньше (да и сейчас, наерно, особенно в функциях IOCTL) была распространена такая практика.  Когда размер отдаваемой структуры был заранее не известен, функцию вызывали 2 раза, первый раз передавали вместо структуры NULL, тогда она отдавала размер который необходим для размещения структуры. Второй раз, когда известно какой будет размер отданной структуры, под нее хапалась память, функции передавался указатель на нее, и она её радостно заполняла требуемымми байтиками.  За распределение/освобождение памяти отвечала вызывающая программа.  Ты не в сказку попал, а в Си вляпался. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В строке 4 последнего скетча написано что-то невразумительное. Например, "sizeof (prefix)" на 8-битной ардуине ВСЕГДА (от слова "совсем всегда") равно 2. Вы этого хотели? Боюсь, что нет

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

 Ты не в сказку попал, а в Си вляпался. 

я жеж и говорю, лживый ваш С )))

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

ua6em пишет:

DetSimen пишет:

 Ты не в сказку попал, а в Си вляпался. 

я жеж и говорю, лживый ваш С )))

Не лживый, а черезчур развязный )))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ua6em пишет:

я жеж и говорю, лживый ваш С )))

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

ua6em пишет:

я жеж и говорю, лживый ваш С )))

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

прямо как в ассемлере )))

Newby
Offline
Зарегистрирован: 22.03.2014

ЕвгенийП пишет:

В строке 4 последнего скетча написано что-то невразумительное. Например, "sizeof (prefix)" на 8-битной ардуине ВСЕГДА (от слова "совсем всегда") равно 2. Вы этого хотели? Боюсь, что нет

Нет, этого я не хотел) prefix в данном случае произвольная си-строка. Вроде компилятор никак не подсвечивал prefix как зарезервированное имя. Но я к слову делаю проект под esp8266 если это что-то меняет.

 

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

если сделать static то содержимое строки будет сохранятся при последующих вызовах функции - а это не нужно

b707 пишет:

а других вариантов, собственно, и нет. Либо заранее выделяете кусок памяти с  запасом, чтобы в него вошла любая из используемых строк, либо пользуетесь malloc. Беспокоится о размере массива в случае очистки не надо, это один из немногих примеров в С++, когда система действует автоматически.

Размер можно посчитать точно, но строка некрасивая и вызывать её несколько раз не хочется. вот через внешний указатель - вполне работает.. если бы только размер тоже считать внутри функции.

  char pref[]="ledbtn_";  //префикс
   int sz=sizeof(numbutton)*(sizeof (pref)+sizeof(numbutton)); //вот так считается размер - хотелось бы  это спрятать внутрь фукнции чтобы не писать каждый раз
   char str[sz]=""; //результирующая строка

CharStrPrefixNum(str,sz,numbutton, pref);


void CharStrPrefixNum (char* string, int sz, int imax, char *prefix){

  char str[sz]=""; //я собираю копию строки и потом копирую её в исходную, но можно и сразу туда по идее
  //Serial.println(sizeof(str));
  for (int i=0; i<imax; ++i){
    char num[sizeof(imax)]; itoa(i,num,DEC);
   strcat(str,prefix);
   strcat(str,num);
   if(i<imax-1){
   strcat(str,",");
   }
   
  }
 strcpy(string,str); \\результат отправляется в переменную по указателю

}

 

DetSimen пишет:
Когда размер отдаваемой структуры был заранее не известен, функцию вызывали 2 раза, первый раз передавали вместо структуры NULL, тогда она отдавала размер который необходим для размещения структуры. Второй раз, когда известно какой будет размер отданной структуры, под нее хапалась память, функции передавался указатель на нее, и она её радостно заполняла требуемымми байтиками. 

Надо подумать... по идее я могу передать вместо указателья на итоговую строку NULL, проверить это условием, посчитать внутри размер и вернуть int размера, инициализировать строку этим размерам и вызвать функцию с указателем на эту строку.. как-то так, пока не тестировал:

 char pref[]="ledbtn_";  //префикс

char str[CharStrPrefixNum(NULL,NULL,numbutton, pref)]; //объявляю строку и вычисляю размер
CharStrPrefixNum(str,sizeof(str),numbutton, pref);



int CharStrPrefixNum (char* string,int sz, int imax, char *prefix){
if (string==NULL){
sz=sizeof(imax)*(sizeof (prefix)+sizeof(imax));
return sz;
} 
else{
  char str[sz]="";
  //Serial.println(sizeof(str));
  for (int i=0; i<imax; ++i){
    char num[sizeof(imax)]; itoa(i,num,DEC);
   strcat(str,prefix);
   strcat(str,num);
   if(i<imax-1){
   strcat(str,",");
   }
   
  }
  strcpy(string,str);
 return sz;
}
}

 

 

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

дык если вы в процедуре измените содержимое строки объявленной static, то как оно сохраниться то при последующем вызове?
я например при вызове функции, возвращающей строку, всегда в первый байт записываю ноль, соотвественно она никогда не повториться.
впрочем все зависит от задачи, учитывая что в МК не так много памяти, передавать функции указатель глобальной строки иногда даже более правильно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Newby пишет:

prefix в данном случае произвольная си-строка

Это не строка, а указатель на символ. Собственно, Ваша ошибка как раз и связана с непониманием этого фундаментального различия. Вы берёте размер указателя, а вовсе не длину строки. А размер указателя всегда одинаковый.

Newby пишет:

Вроде компилятор никак не подсвечивал prefix как зарезервированное имя.

А с чего бы ему подсвечивать? Он никакой гадости не курит.

Newby пишет:

Но я к слову делаю проект под esp8266 если это что-то меняет.

Меняет. sizeof(prefix) на esp8266 равен не 2 (как на Uno) а 4. Всегда 4. Можете напечатать его в Serial и полюбоваться.

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Это не строка, а указатель на символ. Собственно, Ваша ошибка как раз и связана с непониманием этого фундаментального различия. Вы берёте размер указателя

не только этого... товарищ похоже вообще не понимает, зачем нужен оператор sizeof()

В другом месте он берет sizeof() от целого, что он рассчитывает получить?

void CharStrPrefixNum (char* string, int sz, int imax, char *prefix){

  char str[sz]=""; 
  for (int i=0; i<imax; ++i){
    char num[sizeof(imax)]; itoa(i,num,DEC);
   strcat(str,prefix);
   strcat(str,num);
   if(i<imax-1){
   strcat(str,",");
   }
   
  }

 

Newby
Offline
Зарегистрирован: 22.03.2014

ЕвгенийП пишет:

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

Да, это я понял, тогда в функцию стоит передавать не указатель, а копию prefix, без звездочки.. либо придется передавать еще и размер

b707 пишет:

не только этого... товарищ похоже вообще не понимает, зачем нужен оператор sizeof()

В другом месте он берет sizeof() от целого, что он рассчитывает получить?

ну я подозревал, что int всегда занимает одинаковый размер, но кто его знает, вдруг двузначное число будет занимать больше места чем однозначное - лучше лишний раз проверить

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Newby пишет:

ну я подозревал, что int всегда занимает одинаковый размер, но кто его знает, вдруг двузначное число будет занимать больше места чем однозначное - лучше лишний раз проверить

Чем подозревать неведомое, мошт лучше почитать чо-нить?  

b707
Offline
Зарегистрирован: 26.05.2017

Newby пишет:

Да, это я понял, тогда в функцию стоит передавать не указатель, а копию prefix, без звездочки..

похоже что не понял...  "prefix без звездочки" это как раз указатель и есть

Цитата:
я подозревал, что int всегда занимает одинаковый размер, но кто его знает, вдруг двузначное число будет занимать больше места чем однозначное - лучше лишний раз проверить

поэтому вы берете размер целого и используете его для длины строки? - ну не смешите. Признайтесь. в первую очередь самому себе, что вы ни черта не понимаете в строках и указателях и отправляйтесь читать учебник. Худшее. что вы можете сделать в этой ситуации -  делать вид. что "так и задумано"...

Newby
Offline
Зарегистрирован: 22.03.2014

b707 пишет:

похоже что не понял...  "prefix без звездочки" это как раз указатель и есть

поэтому вы берете размер целого и используете его для длины строки? - ну не смешите.

без звездочки вообще не работает...  не компилится. по поводу целого и длины строки - не подумал что размер поменяется при переводе int в строку, спасибо что указали)).Хотя ниже я пытаюсь посчитать размер строки из int - но все равно нужно сперва задать размер для результирующей строки а где его взять? замкнутый круг))

я точно знаю, что imax в функции всегда <10, т.е. строка из этого числа будет 2 байта. Но задавать это явным образом (num[2]) - плохой тон, хотелось чтобы это вычислялось, но как-то пока не выходит.  ну да фиг с ним. В итоге пока что рабочий пример получится такой:

 char pref1[]="greenledbtn_";  //префикс
    char pref2[]="redledbtn_";

//объявляю строку и вычисляю размер
char str1[CharStrPrefixNum(NULL,numbutton, pref1, sizeof(pref1))]="";
CharStrPrefixNum(str1,numbutton, pref1,0);

char str2[CharStrPrefixNum(NULL,numbutton, pref2, sizeof(pref2))]="";
CharStrPrefixNum(str2,numbutton, pref2,0);
//складываю строки
char str[sizeof(str1)+sizeof(str2)]=""; strcat(str,str1);strcat(str,","); strcat(str, str2);

Serial.println(str); //выводит greenledbtn_0,greenledbtn_1,greenledbtn_2,greenledbtn_3,greenledbtn_4,redledbtn_0,redledbtn_1,redledbtn_2,redledbtn_3,redledbtn_4


int CharStrPrefixNum (char*string, int imax, char *prefix, int szpref){
if (string==NULL){
int sz=(imax*(szpref+2)+imax);
return sz;
} 
else{
  for (int i=0; i<imax; ++i){
    char num[2]; itoa(i,num,DEC);
   strcat(string,prefix);
   strcat(string,num);
   if(i<imax-1){
   strcat(string,",");
   }
   
  }

 return 0;
}
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Newby пишет:

Да, это я понял

Ну, если поняли, то и делайте. Зачем Вы вопросы задаёте? Нас экзаменуете?

Newby
Offline
Зарегистрирован: 22.03.2014

ЕвгенийП пишет:

Newby пишет:

Да, это я понял

Ну, если поняли, то и делайте. Зачем Вы вопросы задаёте? Нас экзаменуете?

 

Понял после вашего комментария, и в следующих примерах я как раз передаю размер строки prefix в функцию, так что делаю, да)  но дальше уже новые вопросы появляются)

b707
Offline
Зарегистрирован: 26.05.2017

и что, это компилируется?

//объявляю строку и вычисляю размер
char str1[CharStrPrefixNum(NULL,numbutton, pref1, sizeof(pref1))]="";
CharStrPrefixNum(str1,numbutton, pref1,0);

char str2[CharStrPrefixNum(NULL,numbutton, pref2, sizeof(pref2))]="";
CharStrPrefixNum(str2,numbutton, pref2,0);
//складываю строки
char str[sizeof(str1)+sizeof(str2)]="";

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

Что касается вот этого

char str[sizeof(str1)+sizeof(str2)]="";

что-то мне сдается. что вы опять два размера указателей складываете

Newby
Offline
Зарегистрирован: 22.03.2014

b707 пишет:

и что, это компилируется?

//объявляю строку и вычисляю размер
char str1[CharStrPrefixNum(NULL,numbutton, pref1, sizeof(pref1))]="";
CharStrPrefixNum(str1,numbutton, pref1,0);

char str2[CharStrPrefixNum(NULL,numbutton, pref2, sizeof(pref2))]="";
CharStrPrefixNum(str2,numbutton, pref2,0);
//складываю строки
char str[sizeof(str1)+sizeof(str2)]="";

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

Что касается вот этого

char str[sizeof(str1)+sizeof(str2)]="";

что-то мне сдается. что вы опять два размера указателей складываете

 

Компилируется. Это же вне функции куда передается указатель, поэтому это сама строка, а не указатель. вывод в Serial sizeof(str) выдает 150. ну и строка выводится верно. Также я поправил рассчет размера массива в примере выше в строке 18... видимо про это писали что там не нужен sizeof, но я как-то в упор не догонял о чем речь.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Пидец, на тебя извели целую рощу стоеросового дерева...

Парни, прекращаем подсказывать, пока тему не прочитает и зачёт на здаст. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Newby пишет:

char str[sizeof(str1)+sizeof(str2)]="";

в Serial sizeof(str) выдает 150.

Вы кого хотите обмануть? Себя или нас? Если нас, то не надо - всё равно не поверим. А если себя, так это можно и без форума делать.  Выведите и посмотрите.

Newby пишет:

ну и строка выводится верно.

А вот вот это самая большая подлость этого языка для не желающих учиться новичков. Это называется "распашка памяти". На таком "верно" может всё что угодно быть. например, "сама строка верно", зато пачка других переменных почему-то изменяется. Да и строка ... вроде верно, а через пару строк программы, в которых её не трогают, она вдруг перестаёт быть верной ... Тут всякие шутки возможны.

Может, Вам всё-таки поучиться немного? Книжки почитать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen, я всегда говорил, что "писец" - это профессия раньше была. Люди книжки переписывали. Так они хоть читали их заодно :(

Newby
Offline
Зарегистрирован: 22.03.2014

ЕвгенийП пишет:

Newby пишет:

char str[sizeof(str1)+sizeof(str2)]="";

в Serial sizeof(str) выдает 150.

Вы кого хотите обмануть? Себя или нас? Если нас, то не надо - всё равно не поверим. А если себя, так это можно и без форума делать.  Выведите и посмотрите.

эмм, зачем мне обманывать кого-то? я вывел и сказал что выводится. вот вам скрин если сомневаетесь

вот в хорошем качестве, а то сюда как-то мутно загружается: https://i.postimg.cc/50ZkSzhb/24.jpg

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Newby пишет:
если сомневаетесь
Я не сомневаюсь, я знаю точно, что

char str[sizeof(str1)+sizeof(str2)]="";

Будет иметь реальный размер только в том случае, если str1 и str2 описаны массивами, а не указателями, как Вы описывали раньше

Т.е. они описаны НЕ

char * str1, * str2;

А, например,

char str1[70], str2[80];

вот тогда будет 150.

Newby
Offline
Зарегистрирован: 22.03.2014

ЕвгенийП пишет:

Newby пишет:
если сомневаетесь
Я не сомневаюсь, я знаю точно, что

char str[sizeof(str1)+sizeof(str2)]="";

Будет иметь реальный размер только в том случае, если str1 и str2 описаны массивами, а не указателями, как Вы описывали раньше

Т.е. они описаны НЕ

char * str1, * str2;

А, например,

char str1[70], str2[80];

вот тогда будет 150.

 

Ну так они же так и описаны. Я правда не читал книжек по C, но думаю в данном случае вы немного запутались в моих примерах и поспешили сказать что я обманываю. Насколько я вижу, складываются размеры массивов, а не указателей, вывод в сериал это подтверждает. тыкните пожалуйста где я не прав в комментариях к коду:


    char pref1[]="greenledbtn_";  //это массивы
    char pref2[]="redledbtn_";

//здесь объявляется массив str1. его размер вычисляется и возвращается в виде int функцией. это равносильно написанию char str1[(numbutton*(sizeof(pref1)+2)+numbutton)]="";
char str1[CharStrPrefixNum(NULL,numbutton, pref1, sizeof(pref1))]="";

//здесь в функцию передается указатель на массив str1, по указателю в функции записываются значения в массив str1.
CharStrPrefixNum(str1,numbutton, pref1,0);

//аналогично
char str2[CharStrPrefixNum(NULL,numbutton, pref2, sizeof(pref2))]="";
CharStrPrefixNum(str2,numbutton, pref2,0);

//здесь объявляется массив str и задается его размер.  Sizeof(str1) - определяет размер массива str1 - который был объявлен выше, это не указатель
char str[sizeof(str1)+sizeof(str2)]=""; 

strcat(str,str1);strcat(str,","); strcat(str, str2);

int CharStrPrefixNum (char*string, int imax, char *prefix, int szpref){ //сюда передаются указатели на массивы str1, str2 а также на массивы pref1, pref2
///

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Newby пишет:
думаю в данном случае вы немного запутались в моих примерах

Что есть, то есть, извините.

Вы постоянно выкладываете какие-то куски и огрызки и непонятно к чему они относятся. Привыкайте для вопросов писать отдельный маленький скетч и публикуйте его целиком, чтобы можно было запустить. Причём в каждом новом сообщении (при каждом новом вопросе), выкладывайте текущую версию скетча прямо в этом сообщении, чтобы люди не сомневались к какому именно скетчу относится вопрос. Так будет намного меньше недоразумений и эффективность увеличится.

sadman41
Offline
Зарегистрирован: 19.10.2016

Под ESP можно просто юзать String безо всяких либеральных указателей.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:
безо всяких либеральных указателей.
А авторитарные указатели можно?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

ЕвгенийП пишет:

Люди книжки переписывали. Так они хоть читали их заодно :(

Не только переписывали, ещё и перерисовывали схемы. Заодно стараясь понять как эти самые схемы работают. Две тетради всегда были, одна «черновая», вторая «чистовая». Даже где-то лежат, последние лет 10 на глаза не попадали. Интернет их заменил... (((

b707
Offline
Зарегистрирован: 26.05.2017

BOOM пишет:

Не только переписывали, ещё и перерисовывали схемы.

ну Евгений не про современных копипастов :), а про древних летописцев :) Те тоже переписывали и перерисовывали, а когда чего не понимали или просто скучно было - то и придумывали свое :) поэтому у нас в истории столько интересных событий, причем в каждой летописи - свои :)

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Да я понял, но суть та же. 

Newby
Offline
Зарегистрирован: 22.03.2014

Переписал таким образом чтобы можно было отправлять сразу пачку "префиксов" и склеивать в строку внутри фукнции:

#define number 5 //число элементов 

void setup(){
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  
   const char *pref[]{//префиксы
      "greenled_",
      "redled_",
      "adr_",
      "cmd_",
      "lbl_",
    };
    
    int szpref=sizeof(pref)/sizeof(pref[0]); //число элементов в массиве префиксов

char str[CharStrPrefixNum(NULL, 5, pref,szpref)]=""; //инциализация массива str, вычисление размера

CharStrPrefixNum(str, 5, pref, szpref); //заполнение массива данными

//Serial.println(sizeof(str)); //проверка что правильно считается. выводит 190
//Serial.println(strlen(str)); // выводит 189

  Serial.println(str); //выводит greenled_0,greenled_1,greenled_2,greenled_3,greenled_4,redled_0,redled_1,redled_2,redled_3,redled_4,adr_0,adr_1,adr_2,adr_3,adr_4,cmd_0,cmd_1,cmd_2,cmd_3,cmd_4,lbl_0,lbl_1,lbl_2,lbl_3,lbl_4
}

void loop(){
  
}


int CharStrPrefixNum (char*string, int imax, const char *prefix[], int pSize){
if (string==NULL){ //вычисление размера строки
  int rezSize=0;
  for (int i=0; i<pSize; ++i){ 
    rezSize+=strlen(prefix[i])+1; //+1 на цифру
  };
 rezSize=imax*(rezSize+pSize);

return rezSize;
} 
else{ //заполнение
  
  for (int i=0; i<pSize; ++i){
    for(int j=0; j< imax; ++j){
    char num[2]; itoa(j,num,DEC);
   strcat(string,prefix[i]);
   strcat(string,num);
   if(j<imax-1){
   strcat(string,",");
   }   
  }
  
  if(i<pSize-1){ //еще запятая между данными
strcat(string,",");
  }
  }
 return 0;
}
}

работает)

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Работает без объявления str1 и выделения памяти? Удивительное событие.

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

sadman41 пишет:
безо всяких либеральных указателей.
А авторитарные указатели можно?


Вам здесь можно всё.

Newby
Offline
Зарегистрирован: 22.03.2014

sadman41 пишет:
Работает без объявления str1 и выделения памяти? Удивительное событие.

понятное дело что там просто str должно быть. опечатка при копировании на сайт

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Newby пишет:

понятное дело что там просто str должно быть. опечатка при копировании на сайт

См. #32. Это не было шуткой. Так как Вы себя ведёте - Вас просто будут посылать.

Newby
Offline
Зарегистрирован: 22.03.2014

ЕвгенийП пишет:

Newby пишет:

понятное дело что там просто str должно быть. опечатка при копировании на сайт

См. #32. Это не было шуткой. Так как Вы себя ведёте - Вас просто будут посылать.

не понял к чему это вообще?

я написал целый отдельный рабочий скетч с расширенным функционалом, вопросов у меня по нему нет - выложил для того чтобы принести так сказать пользу обществу - тот кто ищет подобное решение сможет найти и использовать.  

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

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Какой смысл выкладывать "на пользу обществу" с отношением "подумаешь, опечатка" ? Разбираться в неизвестном коде, который даже не компилируется, никто не станет

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Newby пишет:

не понял к чему это вообще?

я написал целый отдельный рабочий скетч с расширенным функционалом, вопросов у меня по нему нет - выложил для того чтобы принести так сказать пользу обществу - тот кто ищет подобное решение сможет найти и использовать.  

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

Пытался помочь Вам адаптироваться здесь (если Вы в этом не нуждаетесь, извините).

А объяснить я пытаюсь простую вещь, которую Вы, похоже, так до сих пор и не поняли.

1. Человек потратил своё время на просмотр Вашего кода и написал про ошибку.
2. Вы - "на самом деле код другой, а в этом опечатка".

Т.е. Вы дали человеку "не тот" код, который у Вас есть на самом деле, а он потратил на него время!

Угадайте сколько раз такое должно произойти, чтобы люди, увидев Ваш код, сразу же начинали думать: да, ну нах в нём разбираться, там опять поди "опечатка"?

Впрочем, далёк от мысли Вам что-то навязывать - это Ваша жизнь. Прекращаю базар.