Массив char
- Войдите на сайт для отправки комментариев
Втр, 16/03/2021 - 21:55
Всем доброго вечера.
Хочу вынести функцию преобразования строки в массив символов.
Типа такого.
char[] retCharArr(String value)
{
char chArray[] = "some characters";
return chArray;
}
Не работает. То что внутри метода (функции) это для тестирования.
Вопросы:
1) вроде нашёл что надо писать так
char * retCharArr(String value)
{
....
}
Т.е. это какой то указатель на массив. Но тогда Этот массив(который я получил из строки) будет вроде внутри метода, его static тогда делать?
2) где-то пишут
char[] chArray = "....";
где-то
char chArray[] = "....";
В чём разница? Или одно относится к массиву символов, а другое к чему то другому?
2) где-то пишут
где-то
Хрена-се вопросики пошли! Ладно, потерпите до завтра.
И кстати, чисто в таком виде как первый пример не пишут (ну, или меня бы это сильно удивило). Подобным образом писать можно, это называется decomposition declaration но ... в общем потерпите до завтра. А пока выложите пример, который Вы видели с первым вариантом, я его завтра прокомментирую заодно.
Вот здесь источник.
Цитата из источника. Ну у меня тема про конвертацию данных из массива в строку и обратно
"...
Конвертировать строку в массив сhar array можно при помощи следующего кода:
String stringVar = “111”;
char charBufVar[20];
stringVar.toCharArray(charBufVar, 20);
Можно сделать обратное преобразование – char to string.
char[] chArray = “start”;
String str(chArray);
"
Массив указателей? Я бы поискал более другую статью.
Конвертировать строку в массив сhar array можно при помощи следующего кода:
зачем это все? У класса String есть готовый метод, который преобразует его в символьный массив без всяких промежуточных функций:
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/c_str/
зачем это все? У класса String есть готовый метод, который преобразует его в символьный массив без всяких промежуточных функций:
Неплохо. Тогда не понятно. При поиске конвертации в инете ссылки идут на что угодно кроме этого метода. Почему?
И всё-таки основной вопрос как "оформить" возврат в методе, чтобы вынести конвертацию в отдельную функцию(метод). Я больше по C# привык. Поэтому больше метод привык.
char[] retCharArr(String value) { char chArray[] = "some characters"; return chArray; }Эта штука не работает. Правильно через указатели (через *) и static?
Через *
ошибка ушла, но в месте где я вызываю данный метод пишет ошибку, что не может определить размер массива.
Нашёл вроде тут про возврат массивов
Б-ть, ну если уж ты String передаёшь, что мешает и возвращать его
String ShitFunc(String &InParam) { String result = "Shit result"; return result; }Дак смысл функции был возвращать массив символов из строки. Накой мне строка возвращаемая.
char *ShitFunc(String &InParam) { return InParam.c_str(); }слов не жалей, когда спрашиваешь.
1char *retCharArr(String value)2{3charchArray[] ="";45returnchArray;6}Только надо передавая строку поставить перед ней&
1char *retCharArr(String &value)2{3charchArray[] ="";4.... преобразования value и добавление к chArray новых данных с изменением размера массива
5returnchArray;6}Так получается?
Небольшие уточнения
1) Повторное использование функции из разных мест несёт какие то нюансы?
2) Как вызвать эту функцию правильно
loop(){ ... char arrEr[16] = retCharArr(""); ... }Не отрабатывает. Даже явно указываю размер, всё равно. Как вообще работает возврат. В C# всё проще :)
incdpr , в описании возвращаемой переменной/массива внутри функции добавьте static
Вот здесь источник.
Можно сделать обратное преобразование – char to string.
Фу, ты, блин, а я уж подумал было и впрямь у Вас вопрос про структурное связывание :-(
Запомните, я здесь это всем и всегда говорю. Литература по программированию - это не любовный роман. Её нельзя читать "по диагонали". Считайте, что Вы не прочитали книгу/статью, если Вы сами не выполнили всех примеров, которые там есть. Именно выполнить - заставить работать, а лучше ещё и немного поменять и убедиться, что поведение меняется предсказуемо - это верный признак того, что Вы понимаете код. Только так научитесь!
Если бы Вы просто взяли этот пример и попытались исполнить, например вот так:
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'и сразу поняли бы, что либо у автора опечатка, либо он чего-то не того покурил. В любом случае - это бред сивой кобылы. Так не объявляют массивы.
Старайтесь следовать этому совету - когда читаете - обязательно исполняйте.
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а лучше ещё и немного поменять и убедиться, что поведение меняется предсказуемо - это верный признак того, что Вы понимаете код. Только так научитесь!
Спасибо Евгений.
В Visual Studio обычно так и делаю. Компиляцию нажал проверил, точки останова, в Debug видимые, локальные переменные посмотрел, матернулся и поправил.
А в Arduino IDE пока только матерки.
Но, я стараюсь учиться. Работы предстоит много. Я своим изобретением на ардуино собираюсь мир изменить. :) Для старта конечно ардуино. Потом я так понимаю, надо будет "свою" ардуино собирать и программатор брать. Поэтому придётся учить "урезанный" ардуинский язык C.
Попробовал настроить Visual Studio Code. Что-то получилось, но как правильно настроить спрошу уже в отдельном вопросе
и сразу поняли бы, что либо у автора опечатка, либо он чего-то не того покурил.
Это, кстати, по тексту статьи сразу понятно - она абсолютно невычитанная. Опечатки, ляпы типа "звездочка указывает на массив указателей" в описании ASCIZ-строк.
Тогда второй вызов функции засрёт результат первого:
согласен, но без него (static) функция вообще ничего не выдаст, т к компилятор просто уберет эту переменную при выходе из функции - нет?
спорить не буду, на днях сам попробую.
Тогда второй вызов функции засрёт результат первого:
согласен, но без него (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 ->получается что функция ничего не выдает?
Функция convert стоит в начале перед setup() - это для наглядности. Или должна стоять раньше вызова?
Функция convert стоит в начале перед setup() - это для наглядности. Или должна стоять раньше вызова?
попробуйте :)
можно после, но тогда компилятор будет ругаться и придется перемещать или сверху отдельно описание вставлять
char * convert(const float f);
по моему всю жисть это писалось по другому - функции передается указатель на внешний массив и она его заполняет
должна стоять раньше вызова?
по нормам языка все используемые сущности, включая и функции с процедурами - должны быть описаны ДО ПЕРВОГО ИСПОЛЬЗОВАНИЯ в коде
То. что Ардуино ИДЕ позволяет отступать от этих правил - обьясняется тем. что Ардуино - среда программирования для детей и создатели ИДЕ позаботились о том, чтобы не забивать мозги детишкам лишними хлопотами
b707 , я конечно не знаю че там у других, но в Keil или вот сейчас в Orange PI пишу, поведение компилятора аналогично Arduino IDE, т е ругается если не объявлено до использования, перемещаю вниз, сверху только объявляю и все хорошо.
ругается если не объявлено до использования, перемещаю вниз, сверху только объявляю и все хорошо.
непонятно, чем это противоречит написанному мной ранее? - процедура должна быть обьявлена до использования - либо полным кодом. либо хидером
непонятно, чем это противоречит написанному мной ранее? - процедура должна быть обьявлена до использования - либо полным кодом. либо хидером
э...да, поспешил с ответом.
я несколько плаваю в терминах, сорри. Забыл. как называется обьявление без тела функции - сейчас глянул в гугле - это прототип.
Я своим изобретением на ардуино собираюсь мир изменить. :) Для старта конечно ардуино. Потом я так понимаю, надо будет "свою" ардуино собирать и программатор брать. Поэтому придётся учить "урезанный" ардуинский язык C.
нет никакого "урезанного языка ардуино", в ардуино используется совершенно полноценный С++ с компилятором gcc. Не учите язык ардуино, учите сразу Си/С++
ЗЫ Почему каждый новичок рассчитывает сразу "изменить мир" ? Может именно потому, что он новичок? Аналогия - чем меньше человек понимает в ботанике - тем больше "неизвестных науке видов" он обнаружит на соседней поляне :)))
по моему всю жисть это писалось по другому - функции передается указатель на внешний массив и она его заполняет
https://www.youtube.com/watch?v=aw10753OJyg :-)
нет никакого "урезанного языка ардуино", в ардуино используется совершенно полноценный С++ с компилятором gcc. Не учите язык ардуино, учите сразу Си/С++
Ну вот опять началось. На одних ресурсах пишут что урезанный, на других что полноценный. Что за ......?
Вопрос уточнение я так понимаю Си и С++ это не одно и то же. Я сейчас не про Visual C++
ЗЫ Почему каждый новичок рассчитывает сразу "изменить мир" ? Может именно потому, что он новичок? Аналогия - чем меньше человек понимает в ботанике - тем больше "неизвестных науке видов" он обнаружит на соседней поляне :)))
Тут весь вопрос в понятии новичок. Если я новичок в ардуино, не означает что я новичок в своей отрасли, которую я хочу изменить с помощью микроэлектроники.
Думаю, что Илон Маск тоже был на старте новичком в электронике создавая электрический автомобиль.
Было бы 1) желание 2) мечта 3) желание реализовать свою мечту
Вопрос уточнение я так понимаю Си и С++ это не одно и то же.
Нет, не одно - это два разных языка.
"Урезанный", потому что ArduinoIDE С++14 из коробки не поддерживает, наверно. А 11 - в полном объеме, включая юниформ-инициализацию и еще много разных ништяков современного С++, о чем редко можно встретить информацию на "ардуино - ресурсах" ))
Хотя, кмк, incdpr не увидел бы разницы))
ArduinoIDE С++14 из коробки не поддерживает, наверно.
Ну, смотря что считать "из коробки". Если для поддержки требуется изменить документированные конфигурационные файлы, то это поддерживает или нет?
В файле platform.txt замените "-std=gnu++11" на "-std=gnu++1z" - будет Вам и 14-ый и 17-ый. Тока ещё две функции лучше добавить, а то при некоторых хитрых кодах будет ошибка компиляции вылезать. Вот тут всё есть.
В файле platform.txt замените "-std=gnu++11" на "-std=gnu++1z" - будет Вам и 14-ый и 17-ый. Тока ещё две функции лучше добавить, а то при некоторых хитрых кодах будет ошибка компиляции вылезать. Вот тут всё есть.
Как я понял, эти манипуляции для каждой платформы нужно повторить (и на каждой машине
). А так да, все как в лучших домах теперь))
Для esp8266 platform.txt несколько отличается от esp32 и AVR
вместо "compiler.cpp.flags" у него присутствует "build.stdcpp_level=-std=gnu++11"
UPD: и правка stdcpp_level предсказуемо не работает :(
Как я понял, эти манипуляции для каждой платформы нужно повторить (и на каждой машине
)
Ну, конфигурационный файл. Нормальное дело.
Для esp8266 platform.txt несколько отличается от esp32 и AVR
вместо "compiler.cpp.flags" у него присутствует "build.stdcpp_level=-std=gnu++11"
Ну, и скажите ему 1z вместо 11.
Ну, и скажите ему 1z вместо 11.
Дополнил предыдущее сообщение. Не компилирует. Теоретически, можно дописать ему эти флаги, но надо понимать, за что отвечают все остальные флаги, кроме версии. А я не понимаю.
В целом, мне не принципиально. Все равно у меня только ESP32 в ходу
Заодно, в ходе научного опыта открыл для себя одну забавную деталь. При каждой проверке скетча IDE повторно перечитывает файлы конфигурации. А я то удивлялся по необразованности, чем оно там так долго занимается... )))
Ну, дык ... "Просите, и дано будет вам; ищите, и найдете; стучите, и отворят вам; ибо всякий просящий получает, и ищущий находит, и стучащему отворят" (Мф. 7:7-8). Держите.
ААА! Он умеет для моей любимой PDP-11 нативный код генерить. Расчехлить эмулятор что ли. Попробовать как оно сработает?
Евгений спасибо! Узнал много нового.
Ну, дык ... "Просите, и дано будет вам; ищите, и найдете; стучите, и отворят вам; ибо всякий просящий получает, и ищущий находит, и стучащему отворят" (Мф. 7:7-8). Держите.
Думал прочитаю по ссылке и начну "подключаться" к магии С++.
Оказалось там всё "непонятными" страшными буквами написано. Пришло понимание что не скоро подключусь :) Нужна разрядка - пару каток в CS GO.
Меньше игры играть, больше книг читать. Что не понятно спрашивать.
Думал прочитаю по ссылке и начну "подключаться" к магии С++.
А Вам вот это лучше. Книжка тоненькая и рассчитанная на совсем новичков (на беременных доярок). Но если Вы её реально изучите (запустите все примеры и заставите их работать и т.п.), то тем, подобной этой, больше не будет.
А Вам вот это лучше. Книжка тоненькая и рассчитанная на совсем новичков (на беременных доярок). Но если Вы её реально изучите (запустите все примеры и заставите их работать и т.п.), то тем, подобной этой, больше не будет.
ЕвгенийП. За этот блокнот - респект тройной.
Вот странная штука здесь опять запись массива корявая, но это дано в качестве ответа. Да ещё и плюсанули 30 раз.
Запустите и проверьте сами.
Я не то что под сомнение. Ошибка то вылазит. Просто непонятно, те кто плюсанул молча исправили, или что там у них? Или их устроило и так.
Вот странная штука здесь опять запись массива корявая, но это дано в качестве ответа. Да ещё и плюсанули 30 раз.
если почитать комменты - в этом ответе поначалу вообще всякая бредятина была написана, уже потом совместными усилиями кое-как исправили...
даже и на Стаковерфлоу не стоит верить каждому ответу, лучше самому книжки читать
Просто непонятно, те кто плюсанул молча исправили, или что там у них? Или их устроило и так.
вероятно всякому. кто знаком с Си - запись char[] array вместо char array[] кажется просто опечаткой. не заслуживающей упоминания в комментах :) Думаю молча исправили и продолжили