c++ - numeros - snprintf arduino
C++ Arduino, uso de sprintf dentro de un método con un parámetro de puntero char, programa de interrupciones (2)
He trabajado la mayor parte del día en este problema y lo he reducido al siguiente programa simple para replicarlo: Test.ino
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
}
// the loop function runs over and over again until power down or reset
void loop() {
char _message[16] = { ''/0'' };
char *message = _message;
int pins[1] = { 1 };
//testOne(pins, 35, 5); // WORKS!!
testTwo(pins, 35, 5, message); // Desn''t Work...
}
void testOne(int sensorPins[], int userDefault, int offset) {
char _int_char[2];
sprintf(_int_char, "%d", 36);
Serial.println(_int_char);
}
void testTwo(int sensorPins[], int userDefault, int offset, char *message) {
char _int_char[2];
sprintf(_int_char, "%d", 37);
Serial.println(_int_char);
}
Todo lo que hace el código anterior es llamar a testOne y probar dos funciones.
La función testOne da el resultado esperado del valor de 36 escrito en la ventana serie para cada iteración del ciclo.
La función testTwo escribe lo siguiente en la ventana serial: "VMDPV_1 | 1_VMVMDPV_1 | 1_VM" .....
Esto solo ocurre cuando agrego el parámetro de mensaje char * a la función. Obviamente, esta es una demostración muy simplificada con valores codificados, etc. En mi código real, utilizo los parámetros y pasan muchas más cosas ...
En realidad, es el llamado a sprintf lo que causa los problemas. En mi código real, uso esto como parte de la construcción del mensaje. Cuando comento la línea sprintf en mi código actual, funciona. Pero, por supuesto, necesito esa línea para obtener el valor de uno de los parámetros en el mensaje.
¿Puede alguien decirme por qué sprintf no funciona en una función que tiene un param de mensaje de char *?
Estoy usando un Arduino UNO y he escrito el código en Visual Studio usando Visual Micro 1511.23.1, que lo hace basado en la instalación IDE de arduino instalada que es 1.6.5.
También he podido replicar esto en el IDE de Arduino, excepto que obtengo caracteres diferentes a "VMDPV_1 ..." ... Obtuve una, 3 una letra O con una coma invertida en la parte superior y un cuadrado.
Estoy desarrollando todo esto en una PC Win 10 64bit.
Gracias por tu tiempo,
Scott
En C, las cadenas tienen 0 terminaciones, lo que significa que después de la llamada a sprintf, _int_char contiene {''3'', ''6'', ''/ 0''}. Esta es una matriz de 3 caracteres y solo reserva la memoria para 2
char _int_char[2];
sprintf(_int_char, "%d", 36);
Su programa produce un comportamiento indefinido debido a un desbordamiento del búfer.
char _int_char[2];
sprintf(_int_char, "%d", 37); // <-- buffer overrun
Como la cadena resultante puede ocupar más de 2 caracteres, el exceso de caracteres sobrepasa la matriz _int_char
y sobrescribe la memoria. Lo que está en la memoria sobrescrita antes de la corrupción puede tener algo que ver con el message
parámetro.
En lugar de crear una matriz de 2 caracteres, declare la matriz lo suficientemente grande como para no producir un desbordamiento del búfer.
char _int_char[20];
sprintf(_int_char, "%d", some_integer);
A menos que tenga enteros que tengan más de 19 dígitos, esto no debería desbordar el búfer.
Una solución infalible, ya que está usando C ++, es usar flujos de C ++, a saber, std :: ostringstream . Entonces no necesita preocuparse por los desbordamientos del búfer, independientemente de la longitud de los datos que se van a generar:
#include <sstream>
#include <string>
//...
std::string _int_char;
std::ostringstream strm;
strm << some_integer;
_int_char << strm.str();