записать в Struct массив char
- Войдите на сайт для отправки комментариев
Сб, 08/02/2020 - 11:00
Вот такой код, орёт error: array must be initialized with a brace-enclosed initializer на строке где я пытаюсь записать переменные в struckt чтобы потом записать в EEPROM , мучаюсь уже 4 дня
#include <EEPROM.h> // Импортируем бмблиотеку
int address = 0; // Переменная для хранения адреса
struct myStruct { // Создаем пользовательскую структуру
float sum; // 4 байта
byte age; // 1 байт
char fullname[15]; // 15 байт - итого 20 байт занимает объект в памяти
};
void setup() {
EEPROM.begin(70) ;
Serial.begin(57600);
float i = 110.20;
byte i1 = 42;
char i2[15] ;
String name = "Ivanov Ivan" ;
name.toCharArray( i2,15) ;
for (int i = 0; i<15 ; i++){
Serial.println(i2[i]) ;
}
Serial.println() ;
Serial.println(i2) ;
myStruct persons = { // Создаем массив объектов пользовательской структуры
i,
i1,
i2
};
// Записываем все данные в EEPROM
EEPROM.put(address, persons); // Записываем значение переменной в EEPROM
address += sizeof(myStruct); // Корректируем адрес следующей записи на объем записываемых данных
// Теперь данные можно считать
address = 0;
myStruct person; // В переменную person будем считывать данные из EEPROM
EEPROM.get(address, person); // Считываем данные из EEPROM в созданную переменную
Serial.println("Чтение пользовательской структуры из EEPROM по адресу: " + String(address));
Serial.println( String(person.sum) + " " +
String(person.age) + " " +
String(person.fullname));
address += sizeof(myStruct); // Корректируем адрес следующей записи на объем записываемых данных
}
void loop() {}
Помучайтесь ещё недельку, а когда научитесь копипастить сообщения компилятора, или хотя бы указывать номера строк, тогда возвращайтесь.
Вот сейчас я всё брошу и начну искать в какой это такой строке Вы пытаетесь "записать переменные в struckt чтобы потом записать в EEPROM".
28myStruct persons = {// Создаем массив объектов пользовательской структуры2930i,31i1,32i23334};Переменная i2 это указатель на массив, а не его содержимое. Поэтому простым примитивным копированием его перенести в структуру не удастся. Структуру нужно объявить не инициализируя в ней массива, а потом скопировать туда массив поэлементно. А лучше сразу прямо записать без промежуточной переменной как сейчас происходит запись в i2.
Я же Вам сказал,
Вы по прежнему не удосужились скопировать сообщение полностью и не указали номер строки в скетче. Возвращайтесь, когда научитесь это делать! И не раньше!
Комрад. Я по образованию ни разу не технарь, я отдельно все слова что ты написал понял....но всё вместе....
дело в том, что я пишу набор опций которые пишуться в EEPROM из html интерфеса, то есть сначала читаем из eeprom struct, потом заменяем один член структуры тем что мы получили из html и снова записываем, для этого мне и нужен String.
вот полный недоработанный код
Тот маленький кусок я выдрал чтобы разбираться с проблеммой поэтапно. Но тут тоже есть корявый момент:
char fullname[15]; void setup() { char fullname1[15]="Petrov"; fullname=fullname1;// а вот здесь такая запись не пройдет.здесь надо ручками } void loop() { }Человеки это существа обладающие неисчерпаемыми запасами лени, и веры божественную халяву. Что и отразилось в данной теме. Что бы решить эту проблему надо ТС освоить приличный объем знаний и временно наплевать на свою религию.
ПС: Пора забыть что написать структуру очень просто. Прежде всего структура это класс с пакетом конструкторов и деструкторов , а также перегрузкой операторов. И если это вам не понятно, читайте соответсующие учебники.
Можно обратица прямо к Руи Сантосу.
Тут есть, наконец-таки, номер строки!!! Как Вы этого не поймёте, что нельзя заставлять человека перерывать весь Ваш код, когда Вам известна строка!
Ваш пост противоречит вашему постулату своим существованием. Посоветуйте где почитать.
Посмотрите внимательнее -> :34: это номер строки
EEPROM_ARDUINO:34:3: error: array must be initialized with a brace-enclosed initializer
Вам ещё нужна помощь? Или уже разобрались? Если нужна, то по какому коду? Из стартового сообщения, или из #5
Если из второго, то что с ним не так (если Вы опять без номеров строк напишете, то просто уйду из темы).
Посмотрите внимательнее -> :34: это номер строки
EEPROM_ARDUINO:34:3: error: array must be initialized with a brace-enclosed initializer
В том-то и дело, что я смотрю внимательно. В стартовом коде строка №34 нормальная, а проблема в строке
32, а вовсе не 34!!!
Т.е. Вы тогда зачем-то показали один код, а сообщение из другого. Вам всё равно что откуда? Или просто поиздеваться решили?
Короче, проехали, впредь показывайте конкретный код и его сообщения, иначе посчитаю, что издеваетесь.
Давайте работать, помощь ещё нужна или разобрались?
spindle, почему неполную структуру написали???
struct sensOptions { // Создаем пользовательскую структуру char SSIDwifi[15]; char passwd[15]; char sName[10]; char adress[15]; char fstart[2]; /*a это куда дели???*/ void setSSIDwifi(String a); void setpasswd(String a); void setsName(String a); void setadress(String a); void setfstart(String a); };Виноват. Я сам потихоньку с ним ковыряюсь, это одна и та же строка.
Так я и спрашиваю, где почитать нормально? Я даже не знал что стракт сам сеттеры создаёт =(
Я даже не знал что стракт сам сеттеры создаёт =(
кто вам такое сказал? - сеттеры надо создавать самому. И в первом коде как раз ошибка в том, что вы их не создали
И опять, направьте где почитать, чтобы доходчиво. С первым кодом разобрался. Беда со вторым
Сейчас он выглядит вот так
#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <EEPROM.h> MDNSResponder mdns; //шаблон для работы с EEPROM , своего рода массив разной инфы int address = 0; struct sensOptions { // Создаем пользовательскую структуру char SSIDwifi[15]; char passwd[15]; char sName[10]; char adress[15]; char fstart[2]; void setSSIDwifi(String a); void setpasswd(String a); void setsName(String a); void setadress(String a); void setfstart(String a); }; String SSIDwifiS ; String passwdS ; String sName ; String adress ; String fstartS ; char ssidcc[15] = " "; char passdcc[15] = " "; char snamecc[10] = " "; char adresscc[15] = " "; char fscc [2] = " "; const uint16_t port = 45000; sensOptions so2 ; sensOptions so1 ; // впишите сюда данные, соответствующие вашей сети: String ssid = "123"; String password = "123"; ESP8266WebServer server(80); IPAddress ip(192,168,1,65); //статический IP IPAddress gateway(192,168,1,1); IPAddress subnet(255,255,255,0); String webPage = ""; void handleRootIP() { eepromRead(); String notice = server.arg("ip"); //надо вставить проверялку правильности IP server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); adress = notice; adress.toCharArray(adresscc,adress.length()) ; eepromWrite() ; //проверяем eepromRead(); } void handleRootSN() { eepromRead(); String notice = server.arg("SN"); server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); } void handleRootSSID() { String notice = server.arg("SSID"); server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); } void handleRootPASSWD() { String notice = server.arg("SSID"); server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); } void eepromRead() { Serial.println("eepromRead") ; // считать данные из EEPROM sensOptions so1; // В переменную person будем считывать данные из EEPROM SSIDwifiS = "" ; passwdS = "" ; sName = "" ; adress = "" ; fstartS = "" ; for(int i = 0 ; i < 15 ; i++) { EEPROM.get(i, so1); SSIDwifiS += String(*so1.SSIDwifi) ; ssidcc[i] = SSIDwifiS[i] ; passwdS += String(*so1.passwd) ; passdcc[i] = passwdS[i]; if(i < 10) { sName += String( *so1.sName) ; snamecc[i] = sName[i]; } adress += String( *so1.adress) ; adresscc[i] = adress[i]; if(i == 0) { fstartS += String(*so1.fstart) ; fscc[i] = so1.fstart[i] ; } } Serial.println(); Serial.println("Чтение пользовательской структуры из EEPROM по адресу: " + String(address)); Serial.println( SSIDwifiS + " " + passwdS + " " + sName + " " + adress + " " + fstartS ); address += sizeof(sensOptions); // Корректируем адрес следующей записи на объем записываемых данных Serial.println("address = " + String(address)) ; } void eepromWrite() { sensOptions so2 = {ssidcc,passdcc,snamecc,adresscc,fscc} ; // EEPROM.put(address, so2); } void setup(void){ delay(1000) ; Serial.begin(57600); EEPROM.begin(70) ; sensOptions so1 = {} ; sensOptions so2 = {} ; webPage += "<p>Sensor options</p> <body><p>Server IP xxx.xxx.xxx.xxx </p> <p><FORM METHOD=\"POST\"action=\"/ip\"><input type=\"text\" name=\"ip\"></p></br></form>" ; webPage += "<p>Sensor Name</p> <p><FORM METHOD=\"POST\"action=\"/sensName\"><input type=\"text\" name=\"SN\"></p></body></br></form>"; webPage += "<p>SSID</p> <p><FORM METHOD=\"POST\"action=\"/SSID\"><input type=\"text\" name=\"SSID\"></p></body></br></form>"; webPage += "<p>wifi password</p> <p><FORM METHOD=\"POST\"action=\"/passwd\"><input type=\"text\" name=\"passwd\"></p></body></br></form>"; delay(1000); eepromRead(); address = 0; if(!fstartS.equals("1")){ Serial.println("This is first Start") ; sensOptions so1 = {"123","123","home1","192.168.1.80","1"} ; EEPROM.put(address, so1); } else { } eepromRead(); //SSIDwifiS.toCharArray(ssid,SSIDwifi.length() +1) ; //passwdS.toCharArray(password,passwdS.length() +1) ; ssid = SSIDwifiS ; password = passwdS ; WiFi.begin(ssid, password); WiFi.config(ip, gateway, subnet); Serial.println(""); // ждем соединения: while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); // "Подключились к " Serial.println(ssid); Serial.print("IP address: "); // "IP-адрес: " Serial.println(WiFi.localIP()); if (mdns.begin("esp8266", WiFi.localIP())) { //прописываемся в ДНС как esp8266 Serial.println("MDNS responder started"); // "Запущен MDNSresponder" } //запускается при начальной странице server.on("/", [](){ server.send(200, "text/html", webPage); }); server.on("/ip", handleRootIP) ; server.on("/sensName", handleRootSN) ; server.on("/SSID", handleRootSSID) ; server.on("/passwd", handleRootPASSWD) ; server.begin(); Serial.println("HTTP server started"); } void loop(void){ server.handleClient(); WiFiClient client; digitalWrite(2, LOW); String ser ; // Use WiFiClient class to create TCP connections while (Serial.available() ) { int inChar ; inChar = Serial.read(); ser += (char)inChar; } while(!client.connect(adress, port)) { delay(10); } if (client.connect(adress, port)) { digitalWrite(2, HIGH); String msg = "1 " + ser ; client.println(msg); //char ch = static_cast<char>(client.read()); delay(5000); } // wait for data to be available /*unsigned long timeout = millis(); while (client.available() == 0) { if (millis() - timeout > 5000) { Serial.println(">>> Client Timeout !"); client.stop(); delay(1000); return; } }*/ delay(10000); }компилятор выдает следующее
struct sensOptions { // Создаем пользовательскую структуру char SSIDwifi[15]; char passwd[15]; char sName[10]; char adress[15]; char fstart[2]; sensOptions(); sensOptions(String a, String b, String c, String d, String e); /*a это куда дели???*/ void setSSIDwifi(String a); void setpasswd(String a); void setsName(String a); void setadress(String a); void setfstart(String a); }; sensOptions::sensOptions() { SSIDwifi[0] = 0; passwd[0] = 0; sName[0] = 0; adress[0] = 0; fstart[0] = 0; } sensOptions::sensOptions(String a, String b, String c, String d, String e) { setSSIDwifi(a) /* ну и так далее */ } void sensOptions::setSSIDwifi(String a) { int i = 0; char *in = a.begin(); while (in[i] != 0) { SSIDwifi[i] = in[i]; i++; if (i >= (15 - 1))break; } SSIDwifi[i] = 0; } /*ну и так далее*/ void setup() { Serial.begin(9600); sensOptions Options; Options.setSSIDwifi("q123456"); Serial.println(Options.SSIDwifi); } void loop() { }где почитать - в учебнике по языку С
Ошибка в том, что у вас в структуре поля описаны как массивы, а ssidcc,passdcc,snamecc,adresscc,fscc - это все не массивы, а ссылки на них.
Вам уже выше написали - массивы простым присваиванием m[34] = d[34]; не копируются, необходимо присваивать каждый элемент массива посимвольно
Я разобрался! Рабочий, но не до конца дописанный (мне не нравится как происходит чтение из EEPROM) код выглядит так:
#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <EEPROM.h> MDNSResponder mdns; //шаблон для работы с EEPROM , своего рода массив разной инфы int address = 0; struct sensOptions { // Создаем пользовательскую структуру char SSIDwifi[15]; char passwd[15]; char sName[10]; char adress[15]; char fstart[2]; void setSSIDwifi(String a); void setpasswd(String a); void setsName(String a); void setadress(String a); void setfstart(String a); }; String SSIDwifiS ; String passwdS ; String sName ; String adress ; String fstartS ; char ssidcc[15] = " "; char passdcc[15] = " "; char snamecc[10] = " "; char adresscc[15] = " "; char fscc [2] = " "; const uint16_t port = 45000; sensOptions so2 ; sensOptions so1 ; // впишите сюда данные, соответствующие вашей сети: String ssid = "123"; String password = "123"; ESP8266WebServer server(80); IPAddress ip(192,168,1,65); //статический IP IPAddress gateway(192,168,1,1); IPAddress subnet(255,255,255,0); String webPage = ""; void handleRootIP() { eepromRead(); String notice = server.arg("ip"); //надо вставить проверялку правильности IP server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); adress = notice; //adress.toCharArray(adresscc,adress.length()) ; for(int i = 0; i <= adress.length() ; i++) { so2.adress[i] = adress[i] ; } eepromWrite() ; Serial.println("Check") ; eepromRead(); } void handleRootSN() { eepromRead(); String notice = server.arg("SN"); server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); } void handleRootSSID() { String notice = server.arg("SSID"); server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); } void handleRootPASSWD() { String notice = server.arg("SSID"); server.send(200, "text/html", webPage); Serial.print("Argument Received = "); Serial.println (notice); } void eepromRead() { Serial.println("eepromRead") ; // считать данные из EEPROM sensOptions so1; // В переменную person будем считывать данные из EEPROM SSIDwifiS = "" ; passwdS = "" ; sName = "" ; adress = "" ; fstartS = "" ; for(int i = 0 ; i < 15 ; i++) { EEPROM.get(i, so1); SSIDwifiS += String(*so1.SSIDwifi) ; //ssidcc[i] = SSIDwifiS[i] ; so2.SSIDwifi[i] = SSIDwifiS[i]; passwdS += String(*so1.passwd) ; //passdcc[i] = passwdS[i]; so2.passwd[i] = passwdS[i]; ; if(i < 10) { sName += String( *so1.sName) ; //snamecc[i] = sName[i]; so2.sName[i] = sName[i]; } adress += String( *so1.adress) ; //adresscc[i] = adress[i]; so2.adress[i] = adress[i]; if(i == 0) { fstartS += String(*so1.fstart) ; //fscc[i] = so1.fstart[i] ; so2.fstart[i] = fstartS[i]; } } Serial.println(); Serial.println("Чтение пользовательской структуры из EEPROM по адресу: " + String(address)); Serial.println( SSIDwifiS + " " + passwdS + " " + sName + " " + adress + " " + fstartS ); address += sizeof(sensOptions); // Корректируем адрес следующей записи на объем записываемых данных Serial.println("address = " + String(address)) ; } void eepromWrite() { address = 0 ; EEPROM.put(address, so2); } void setup(void){ delay(1000) ; Serial.begin(57600); EEPROM.begin(70) ; sensOptions so1 = {} ; sensOptions so2 = {} ; webPage += "<p>Sensor options</p> <body><p>Server IP xxx.xxx.xxx.xxx </p> <p><FORM METHOD=\"POST\"action=\"/ip\"><input type=\"text\" name=\"ip\"></p></br></form>" ; webPage += "<p>Sensor Name</p> <p><FORM METHOD=\"POST\"action=\"/sensName\"><input type=\"text\" name=\"SN\"></p></body></br></form>"; webPage += "<p>SSID</p> <p><FORM METHOD=\"POST\"action=\"/SSID\"><input type=\"text\" name=\"SSID\"></p></body></br></form>"; webPage += "<p>wifi password</p> <p><FORM METHOD=\"POST\"action=\"/passwd\"><input type=\"text\" name=\"passwd\"></p></body></br></form>"; delay(1000); eepromRead(); address = 0; if(!fstartS.equals("1")){ Serial.println("This is first Start") ; sensOptions so1 = {"123","123","home1","192.168.1.80","1"} ; EEPROM.put(address, so1); } else { } eepromRead(); //SSIDwifiS.toCharArray(ssid,SSIDwifi.length() +1) ; //passwdS.toCharArray(password,passwdS.length() +1) ; ssid = SSIDwifiS ; password = passwdS ; WiFi.begin(ssid, password); WiFi.config(ip, gateway, subnet); Serial.println(""); // ждем соединения: while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); // "Подключились к " Serial.println(ssid); Serial.print("IP address: "); // "IP-адрес: " Serial.println(WiFi.localIP()); if (mdns.begin("esp8266", WiFi.localIP())) { //прописываемся в ДНС как esp8266 Serial.println("MDNS responder started"); // "Запущен MDNSresponder" } //запускается при начальной странице server.on("/", [](){ server.send(200, "text/html", webPage); }); server.on("/ip", handleRootIP) ; server.on("/sensName", handleRootSN) ; server.on("/SSID", handleRootSSID) ; server.on("/passwd", handleRootPASSWD) ; server.begin(); Serial.println("HTTP server started"); } void loop(void){ server.handleClient(); WiFiClient client; digitalWrite(2, LOW); String ser ; // Use WiFiClient class to create TCP connections while (Serial.available() ) { int inChar ; inChar = Serial.read(); ser += (char)inChar; } while(!client.connect(adress, port)) { delay(10); } if (client.connect(adress, port)) { digitalWrite(2, HIGH); String msg = "1 " + ser ; client.println(msg); //char ch = static_cast<char>(client.read()); delay(5000); } // wait for data to be available /*unsigned long timeout = millis(); while (client.available() == 0) { if (millis() - timeout > 5000) { Serial.println(">>> Client Timeout !"); client.stop(); delay(1000); return; } }*/ delay(10000); }пост QWONE направил меня в нужную сторону. Всем большое спасибо, прошу не сердиться на меня.
Не совсем так но я пробовал, String не пишеться в EEPROM, поэтому я через цикл for и передал из стринга значения в char[], теперь заработало. Ваш пример разберу поглубже. Спасибо.
Я понимаю что в учебниках. У меня есть древний учебник по-моему Липтона. Там сам чёрт ногу сломит. Я поэтому и спрашиваю чего-то конкретного, доходчивого, а не давайте построим МКС, а на 500й страницу подробного описания механики работы ионных двигателей наконец перейдём к изучению работы ручной мясорубки.
Это всё не отменяет необходимости базовых знаний. В первой теме песочницы есть ссылки на литературу, которую знать обязательно (без неё просто нечего делать в программировании). В первую очередь - К&R (это ветхий завет - знать надо наизусть), и во вторую - Страуструп - это новый завет. Без этих знаний у Вас будут постоянно возникать проблемы на ровном месте.
Так что не отверчивайтесь, а учитесь.
А если учится дальше, то уже читать литературу от "протестантов" https://docs.microsoft.com/ru-ru/cpp/cpp/cpp-language-reference?view=vs-2019
Пух, это справочник. Чтобы его читать и понимать, базовые знания уже нужно иметь.
А для себя с закладку сделал, спасибо, этого справочника я ещё не видел.
Не надо читать кр, а следом страуструпа. В страуструпе 95% от кр повторено, а остальные 5 к арудино не применимы.
rkit, давайте Вы не будете писать глупости, ладно? Если это случайно вышло, я могу стереть тот Ваш пост (вместе с этим), скажите - сделаю.
Не надо читать кр, а следом страуструпа. В страуструпе 95% от кр повторено, а остальные 5 к арудино не применимы.