Проблема с функцией toCharArray

sermal
Offline
Зарегистрирован: 20.10.2012

У меня 3 переменные типа String, мне следует их преобразовать в char[] и дальше использовать по коду. Если я делаю вывод первой переменной сразу после конвертации, то все ок. Если вывожу ее состояние после конвертации второй переменной, то значение первой превращается в пусто.

Вот примеры:

1. Code:
    char _ssid[ssid.length()];
    ssid.toCharArray(_ssid, ssid.length()+1);
    Serial.println(_ssid);
    
    char _pass[pass.length()];
    pass.toCharArray(_pass, pass.length()+1);
    Serial.println(_pass);
    
    char _key[key.length()];
    key.toCharArray(_key, key.length()+1);
    Serial.println(_key);

Result:
    a_dcg
    j3qq4h7h2v
    D0D0DEADF00DABBADEAFBEADED

2. Code:
    char _ssid[ssid.length()];
    ssid.toCharArray(_ssid, ssid.length()+1);
    Serial.println(_ssid);
    
    char _pass[pass.length()];
    pass.toCharArray(_pass, pass.length()+1);
    
    char _key[key.length()];
    key.toCharArray(_key, key.length()+1);
    Serial.println(_key);
    Serial.println(_pass);
Result:
    a_dcg
    D0D0DEADF00DABBADEAFBEADED

3. Code:
    char _ssid[ssid.length()];
    ssid.toCharArray(_ssid, ssid.length()+1);
    
    char _pass[pass.length()];
    pass.toCharArray(_pass, pass.length()+1);
    
    char _key[key.length()];
    key.toCharArray(_key, key.length()+1);
    
    Serial.println(_ssid);
    Serial.println(_pass);
    Serial.println(_key);

Result:

    D0D0DEADF00DABBADEAFBEADED

 

Что я делаю не так?

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

Выход за пределы массива тому причина. 

Вы же в функцию передаете длинну на 1 больше:

key.toCharArray(_key, key.length()+1);

поэтому выходите за пределы объявленного массива. Надо увеличить длинну массива на 1 при объявлении:

char _key[key.length()+1];
sermal
Offline
Зарегистрирован: 20.10.2012

Добавление единицы свяазано с тем, что без этого был укорочен результат на один символ . Так в первом примере верно все выводится:

a_dcg
j3qq4h7h2v
D0D0DEADF00DABBADEAFBEADED

А когда просто переношу строку вывода переменной ниже, то уже не выводится.

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

И???

sermal
Offline
Зарегистрирован: 20.10.2012

вопрос остается таким же, почему так работает

    char _ssid[ssid.length()];
    ssid.toCharArray(_ssid, ssid.length()+1);
    Serial.println(_ssid);
    
    char _pass[pass.length()];
    pass.toCharArray(_pass, pass.length()+1);
    Serial.println(_pass);

 

а так уже нет? _ssid содержит уже пусто.

    char _ssid[ssid.length()];
    ssid.toCharArray(_ssid, ssid.length()+1);
    
    char _pass[pass.length()];
    pass.toCharArray(_pass, pass.length()+1);
    Serial.println(_pass);

    Serial.println(_ssid);

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

Я понять не могу вы куда смотрите? вы сообщение #1 до конца дочитали?

 

maksim пишет:

Надо увеличить длинну массива на 1 при объявлении:

char _key[key.length()+1];

 

sermal
Offline
Зарегистрирован: 20.10.2012

Дочитал =) и не один раз.

Так ведь работает. И увеличивать не надо.

    char _ssid[ssid.length()];
    ssid.toCharArray(_ssid, ssid.length()+1);
    Serial.println(_ssid);

Я не могу понять, как вывод переменной в другом месте влияет на состояние самой переменной?

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

Я же вам написал.
Вы выходите за пределы объявленного массива, то есть работаете с памятью не зная что в ней находится. В данном конкретном случае так получилось, что вы при заполнении последующего массива записываете последний символ \0 в первый элемент предыдущего массива.

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

Вот смотрите.
Объявим массив размером 5 элементов, а заполним 6 элементов:

 char Array[5];
  Array[0] = 'A'; // раз
  Array[1] = 'B'; // два
  Array[2] = 'C'; // три
  Array[3] = 'D'; // четыре
  Array[4] = 'E'; // пять
  Array[5] = 0;   // и шесть - конец строки
  // именно поэтому вы и прибавляете 1, 
  // потому как toCharArray в последний элемент массива записывает 0 
  Serial.println(Array);

все хорошо не смотря на то что мы вышли за пределы.
А теперь объявим два массива:

  char Array[5];
  Array[0] = 'A'; // раз
  Array[1] = 'B'; // два
  Array[2] = 'C'; // три
  Array[3] = 'D'; // четыре
  Array[4] = 'E'; // пять
  Array[5] = 0;   // и шесть - конец строки

  char Array2[5];
  Array2[0] = 'A'; // раз
  Array2[1] = 'B'; // два
  Array2[2] = 'C'; // три
  Array2[3] = 'D'; // четыре
  Array2[4] = 'E'; // пять
  Array2[5] = 0;   // конец строки. 
  
  Serial.println(Array);
  Serial.println(Array2);

 

Вот этот вот самый последний 0 на самом деле записывается не в Array2[5] (потомучто такого элемента массива не существует), а в Array[0]. Просто так сложилось что в памяти следующий байт именно этот. Serial.println выводит строку пока не встретит в этой строке 0 ('\0'), а у вас этот 0 оказывается в самом начале строки и поэтому строка не выводится.

 

sermal
Offline
Зарегистрирован: 20.10.2012

Как доберусь до Arduino, попробую сделать. Отпишусь о результате.

sermal
Offline
Зарегистрирован: 20.10.2012

Заработало, спасибо!

feartat
Offline
Зарегистрирован: 01.11.2017

Здравствуйте уважаемые, у меня вопрос из той же оперы.

Дано:

 char curarray[3];
MSGtxt.toCharArray(curarray,3);	
	Serial.println(curarray);
	Serial.println("litera");
	Serial.println(curarray[0]);
	Serial.println("nomer");
	Serial.println(curarray[1]);

результат строки 3: A9

Результат строки 5: А

результат строки 7: 9

далее

if (curarray[0]=='A') 
		{
			for (int j=0;j<curarray[1];j++);{
			
			Serial.println("Step "+ String(i,DEC)+"."+String(j,DEC));
			Serial.println("UP");
			movefwd();}
		}

Цикл не идет.

пробовал в строке 3:

for (int j=0;j<curarray[1];j++)
for (int j=0;j<atoi(curarray[1]);j++)
for (int j=0;j<int(curarray[1]);j++)

Результат нулевой. Что я делаю не так?

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Может ; после for не нужна

feartat
Offline
Зарегистрирован: 01.11.2017

Спасибо бро! Затупил ))

Но все равно преобразование типов у меня нормально не работает. вместо заявленных 10 шагов он делает 56.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

В другой теме же объясняли про символы и байты ) выполните serial.printl(curarray[1], DEC) там будет далеко не то что ожидаете, надо 48 вычесть чтобы получить из символа цифру

feartat
Offline
Зарегистрирован: 01.11.2017

Спасибо )