Массив char

incdpr
Offline
Зарегистрирован: 28.11.2020

Всем доброго вечера.

Хочу вынести функцию преобразования строки в массив символов.

Типа такого.

char[] retCharArr(String value)
{
  	char chArray[] = "some characters";

  	return chArray;
}

Не работает. То что внутри метода (функции) это для тестирования. 

Вопросы:

1) вроде нашёл что надо писать так 


char * retCharArr(String value)
{
....
}

Т.е. это какой то указатель на массив. Но тогда Этот массив(который я получил из строки) будет вроде внутри метода, его static тогда делать?

2) где-то пишут 

char[] chArray = "....";

где-то

char chArray[] = "....";

В чём разница? Или одно относится к массиву символов, а другое к чему то другому?

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

incdpr пишет:

2) где-то пишут 

char[] chArray = "....";

где-то

char chArray[] = "....";

Хрена-се вопросики пошли! Ладно, потерпите до завтра.

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

incdpr
Offline
Зарегистрирован: 28.11.2020

Вот здесь источник.

Цитата из источника. Ну у меня тема про конвертацию данных из массива в строку и обратно

"...

Конвертировать строку в массив сhar array можно при помощи следующего кода:

String stringVar = “111”;

char charBufVar[20];

stringVar.toCharArray(charBufVar, 20);

Можно сделать обратное преобразование – char to string.

char[] chArray = “start”;

String str(chArray);

"

 

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

Массив указателей? Я бы поискал более другую статью.

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

incdpr пишет:

Конвертировать строку в массив сhar array можно при помощи следующего кода:

зачем это все? У класса String есть готовый метод, который преобразует его в символьный массив без всяких промежуточных функций:

https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/c_str/

incdpr
Offline
Зарегистрирован: 28.11.2020

b707 пишет:

зачем это все? У класса String есть готовый метод, который преобразует его в символьный массив без всяких промежуточных функций:

Неплохо. Тогда не понятно. При поиске конвертации в инете ссылки идут на что угодно кроме этого метода. Почему?

И всё-таки основной вопрос как "оформить" возврат в методе, чтобы вынести конвертацию в отдельную функцию(метод). Я больше по C# привык. Поэтому больше метод привык.


char[] retCharArr(String value)
{
    char chArray[] = "some characters";
    return chArray;
}

Эта штука не работает. Правильно через указатели (через *) и static?

 

Через *

char  * retCharArr(String value)...

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

incdpr
Offline
Зарегистрирован: 28.11.2020

Нашёл вроде тут про возврат массивов

 

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

Б-ть, ну если уж ты String передаёшь, что мешает и возвращать его

String ShitFunc(String &InParam) {
  String result = "Shit result";
  return result;
}

 

incdpr
Offline
Зарегистрирован: 28.11.2020

Дак смысл функции был возвращать массив символов из строки. Накой мне строка возвращаемая.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
char *ShitFunc(String &InParam) {
  return InParam.c_str();
}

слов не жалей, когда спрашиваешь. 

incdpr
Offline
Зарегистрирован: 28.11.2020
Погоди, погоди. Не уходи пока. Уточнения есть :)
 
Смысл в том, что я эту строку в функции хотел парсить.
 
Ну я так понимаю, что разницы нет если я сделаю, так как писал только через *

 

1 char * retCharArr(String value)
2 {
3     char chArray[] = "";
4  
5     return chArray;
6 }

Только надо передавая строку поставить перед ней&

1 char * retCharArr(String &value)
2 {
3     char chArray[] = "";
4  

 .... преобразования value и добавление к chArray новых данных с изменением размера массива

5     return chArray;
6 }

Так получается?

Небольшие уточнения

1) Повторное использование функции из разных мест несёт какие то нюансы?

2) Как вызвать эту функцию правильно

loop(){
...

char arrEr[16] = retCharArr("");
...
}

Не отрабатывает. Даже явно указываю размер, всё равно. Как вообще работает возврат. В C# всё проще :)

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

incdpr , в описании возвращаемой переменной/массива внутри функции добавьте static

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

incdpr пишет:

Вот здесь источник.

Можно сделать обратное преобразование – char to string.

char[] chArray = “start”;
String str(chArray);

Фу, ты, блин, а я уж подумал было и впрямь у Вас вопрос про структурное связывание :-(

Запомните, я здесь это всем и всегда говорю. Литература по программированию - это не любовный роман. Её нельзя читать "по диагонали". Считайте, что Вы не прочитали книгу/статью, если Вы сами не выполнили всех примеров, которые там есть. Именно выполнить - заставить работать, а лучше ещё и немного поменять и убедиться, что поведение меняется предсказуемо - это верный признак того, что Вы понимаете код. Только так научитесь!

Если бы Вы просто взяли этот пример и попытались исполнить, например вот так:

void setup() {
	char[] chArray = "start";
	String str(chArray);
	Serial.begin(9600);
	Serial.println(str);
}
void loop(void) {}

Вы бы получили вот такой отлуп от компилятора

D:\Soft\Kaka.ino: In function 'void setup()':
Kaka:2:6: error: decomposition declaration cannot be declared with type 'char'
  char[] chArray = "start";
      ^~
D:\GoogleD\Soft\Kaka\Kaka\Kaka.ino:2:6: note: type must be cv-qualified 'auto' or reference to cv-qualified 'auto'
Kaka:2:6: error: empty decomposition declaration
Kaka:2:9: error: expected initializer before 'chArray'
  char[] chArray = "start";
         ^~~~~~~
Kaka:3:13: error: 'chArray' was not declared in this scope
  String str(chArray);
             ^~~~~~~
exit status 1
decomposition declaration cannot be declared with type 'char'

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

Старайтесь следовать этому совету - когда читаете - обязательно исполняйте.

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

andycat пишет:

incdpr , в описании возвращаемой переменной/массива внутри функции добавьте static

Тогда второй вызов функции засрёт результат первого:

char * convert(const float f) {
	static char buff[12];
	dtostrf(f, 11, 4, buff);
	return buff;
}

void setup() {
	Serial.begin(9600);
	float _pi = 3.141592;
	float _e  = 2.718282;
	char * sPI = convert(_pi); // всё ок
	Serial.println(sPI); 		// убеждаемся
	char * sE = convert(_e);	// sE в порядке, но sPI уже засрано
	Serial.println(sE); 		// убеждаемся, что sE в порядке
	Serial.println(sPI);		// убеждаемся, что sPI уже засрано
}
void loop(void) {}

результат исполнения

     3.1416
     2.7183
     2.7183
incdpr
Offline
Зарегистрирован: 28.11.2020

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

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

Спасибо Евгений.

В Visual Studio обычно так и делаю. Компиляцию нажал проверил, точки останова, в Debug видимые, локальные переменные посмотрел, матернулся и поправил.

А в Arduino IDE пока только матерки.

Но, я стараюсь учиться. Работы предстоит много. Я своим изобретением на ардуино собираюсь мир изменить. :) Для старта конечно ардуино. Потом я так понимаю, надо будет "свою" ардуино собирать и программатор брать. Поэтому придётся учить "урезанный" ардуинский язык C. 

Попробовал настроить Visual Studio Code. Что-то получилось, но как правильно настроить спрошу уже в отдельном вопросе

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

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

и сразу поняли бы, что либо у автора опечатка, либо он чего-то не того покурил. 

Это, кстати, по тексту статьи сразу понятно - она абсолютно невычитанная. Опечатки, ляпы типа "звездочка указывает на массив указателей" в описании ASCIZ-строк.

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

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

Тогда второй вызов функции засрёт результат первого:

согласен, но без него (static) функция вообще ничего не выдаст, т к компилятор просто уберет эту переменную при выходе из функции - нет?
спорить не буду, на днях сам попробую.

 

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

andycat пишет:

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

Тогда второй вызов функции засрёт результат первого:

согласен, но без него (static) функция вообще ничего не выдаст, т к компилятор просто уберет эту переменную при выходе из функции - нет?
спорить не буду, на днях сам попробую.

попробовал без static

char * convert(const float f) {
  char buff[12];
  dtostrf(f, 11, 4, buff);
  return buff;
}

void setup() {
  Serial.begin(9600);
  float _pi = 3.141592;
  float _e  = 2.718282;
  char * sPI = convert(_pi); // всё ок
  Serial.println(sPI);    // убеждаемся
  char * sE = convert(_e);  // sE в порядке, но sPI уже засрано
  Serial.println(sE);     // убеждаемся, что sE в порядке
  Serial.println(sPI);    // убеждаемся, что sPI уже засрано
}
void loop(void) {}


13:01:15.376 -> 
13:01:15.376 -> 
13:01:15.376 -> 

получается что функция ничего не выдает?

incdpr
Offline
Зарегистрирован: 28.11.2020

Функция convert стоит в начале перед setup() - это для наглядности. Или должна стоять раньше вызова?

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

incdpr пишет:

Функция convert стоит в начале перед setup() - это для наглядности. Или должна стоять раньше вызова?

попробуйте :)

можно после, но тогда компилятор будет ругаться и придется перемещать или сверху отдельно описание вставлять 

char * convert(const float f);

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

по моему всю жисть это писалось по другому - функции передается указатель на внешний массив и она его заполняет

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

incdpr пишет:

должна стоять раньше вызова?

по нормам языка все используемые сущности, включая и функции с процедурами - должны быть описаны ДО ПЕРВОГО ИСПОЛЬЗОВАНИЯ в коде

То. что Ардуино ИДЕ позволяет отступать от этих правил - обьясняется тем. что Ардуино - среда программирования для детей и создатели ИДЕ позаботились о том, чтобы не забивать мозги детишкам лишними хлопотами

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

b707 , я конечно не знаю че там у других, но в Keil или вот сейчас в Orange PI пишу, поведение компилятора аналогично Arduino IDE, т е ругается если не объявлено до использования, перемещаю вниз, сверху только объявляю и все хорошо.

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

andycat пишет:

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

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

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

b707 пишет:

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

э...да, поспешил с ответом.

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

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

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

incdpr пишет:

Я своим изобретением на ардуино собираюсь мир изменить. :) Для старта конечно ардуино. Потом я так понимаю, надо будет "свою" ардуино собирать и программатор брать. Поэтому придётся учить "урезанный" ардуинский язык C.

нет никакого "урезанного языка ардуино", в ардуино используется совершенно полноценный С++ с компилятором gcc. Не учите язык ардуино, учите сразу Си/С++

ЗЫ Почему каждый новичок рассчитывает сразу "изменить мир" ? Может именно потому, что он новичок? Аналогия - чем меньше человек понимает в ботанике - тем больше "неизвестных науке видов" он обнаружит на соседней поляне :)))

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

b707 пишет:

по моему всю жисть это писалось по другому - функции передается указатель на внешний массив и она его заполняет

https://www.youtube.com/watch?v=aw10753OJyg :-)

incdpr
Offline
Зарегистрирован: 28.11.2020

b707 пишет:

нет никакого "урезанного языка ардуино", в ардуино используется совершенно полноценный С++ с компилятором gcc. Не учите язык ардуино, учите сразу Си/С++

Ну вот опять началось. На одних ресурсах пишут что урезанный, на других что полноценный. Что за ......?

Вопрос уточнение я так понимаю Си и С++ это не одно и то же. Я сейчас не про Visual C++

b707 пишет:

ЗЫ Почему каждый новичок рассчитывает сразу "изменить мир" ? Может именно потому, что он новичок? Аналогия - чем меньше человек понимает в ботанике - тем больше "неизвестных науке видов" он обнаружит на соседней поляне :)))

Тут весь вопрос в понятии новичок. Если я новичок в ардуино, не означает что я новичок в своей отрасли, которую я хочу изменить с помощью микроэлектроники.

Думаю, что Илон Маск тоже был на старте новичком в электронике создавая электрический автомобиль.

Было бы 1) желание 2) мечта 3) желание реализовать свою мечту

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

incdpr пишет:

Вопрос уточнение я так понимаю Си и С++ это не одно и то же. 

Нет, не одно - это два разных языка.

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

"Урезанный", потому что ArduinoIDE С++14 из коробки не поддерживает, наверно. А 11 - в полном объеме, включая юниформ-инициализацию и еще много разных ништяков современного С++, о чем редко можно встретить информацию на "ардуино - ресурсах" )) 

Хотя, кмк, incdpr не увидел бы разницы))

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

Rumata пишет:

ArduinoIDE С++14 из коробки не поддерживает, наверно.

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

В файле platform.txt замените "-std=gnu++11" на "-std=gnu++1z" - будет Вам и 14-ый и 17-ый. Тока ещё две функции лучше добавить, а то при некоторых хитрых кодах будет ошибка компиляции вылезать. Вот тут всё есть.

 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

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

В файле platform.txt замените "-std=gnu++11" на "-std=gnu++1z" - будет Вам и 14-ый и 17-ый. Тока ещё две функции лучше добавить, а то при некоторых хитрых кодах будет ошибка компиляции вылезать. Вот тут всё есть.

 Как я понял, эти манипуляции для каждой платформы нужно повторить (и на каждой машине ). А так да, все как в лучших домах теперь)) 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Для esp8266 platform.txt несколько отличается от esp32 и  AVR

вместо "compiler.cpp.flags" у него присутствует "build.stdcpp_level=-std=gnu++11" 

UPD:  и правка stdcpp_level предсказуемо не работает :( 

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

Rumata пишет:

 Как я понял, эти манипуляции для каждой платформы нужно повторить (и на каждой машине )

Ну, конфигурационный файл. Нормальное дело.

Rumata пишет:

Для esp8266 platform.txt несколько отличается от esp32 и  AVR

вместо "compiler.cpp.flags" у него присутствует "build.stdcpp_level=-std=gnu++11" 

Ну, и скажите ему 1z вместо 11.

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

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

Ну, и скажите ему 1z вместо 11.

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

В целом, мне не принципиально. Все равно у меня только ESP32 в ходу

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Заодно, в ходе научного опыта открыл для себя одну забавную деталь. При каждой проверке скетча IDE повторно перечитывает файлы конфигурации. А я то удивлялся по необразованности, чем оно там так долго занимается... )))

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

Rumata пишет:
надо понимать, за что отвечают все остальные флаги, кроме версии. А я не понимаю.

Ну, дык ... "Просите, и дано будет вам; ищите, и найдете; стучите, и отворят вам; ибо всякий просящий получает, и ищущий находит, и стучащему отворят" (Мф. 7:7-8). Держите.

nik182
Offline
Зарегистрирован: 04.05.2015

ААА! Он умеет для моей любимой PDP-11 нативный код генерить. Расчехлить эмулятор что ли. Попробовать как оно сработает?

Евгений спасибо! Узнал много нового.

incdpr
Offline
Зарегистрирован: 28.11.2020

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

Ну, дык ... "Просите, и дано будет вам; ищите, и найдете; стучите, и отворят вам; ибо всякий просящий получает, и ищущий находит, и стучащему отворят" (Мф. 7:7-8). Держите.

Думал прочитаю по ссылке и начну "подключаться" к магии С++.

Оказалось там всё "непонятными" страшными буквами написано. Пришло понимание что не скоро подключусь :) Нужна разрядка - пару каток в CS GO.

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

Меньше игры играть, больше книг читать. Что не понятно спрашивать. 

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

incdpr пишет:

Думал прочитаю по ссылке и начну "подключаться" к магии С++.

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

incdpr
Offline
Зарегистрирован: 28.11.2020

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

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

ЕвгенийП. За этот блокнот - респект тройной.

incdpr
Offline
Зарегистрирован: 28.11.2020

Вот странная штука здесь опять запись массива корявая, но это дано в качестве ответа. Да ещё и плюсанули 30 раз.

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

Запустите и проверьте сами.

incdpr
Offline
Зарегистрирован: 28.11.2020

Я не то что под сомнение. Ошибка то вылазит. Просто непонятно, те кто плюсанул молча исправили, или что там у них? Или их устроило и так.

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

incdpr пишет:

Вот странная штука здесь опять запись массива корявая, но это дано в качестве ответа. Да ещё и плюсанули 30 раз.

если почитать комменты - в этом ответе поначалу вообще всякая бредятина была написана, уже потом совместными усилиями кое-как исправили...

даже и на Стаковерфлоу не стоит верить каждому ответу, лучше самому книжки читать

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

incdpr пишет:

Просто непонятно, те кто плюсанул молча исправили, или что там у них? Или их устроило и так.

вероятно всякому. кто знаком с Си - запись char[] array вместо char array[] кажется просто опечаткой. не заслуживающей упоминания в комментах :) Думаю молча исправили и продолжили