Quiero imprimir texto y números mezclados en una tabla con Serial.print (); de una matriz de caracteres. Mi problema es la conversión entre los diferentes tipos de datos. Mi idea es imprimir los datos de las filas en un bucle for con la variable i y las columnas en un bucle for con la variable j.
Tengo en el siguiente ejemplo dos variables, una es de tipo integer y el segundo es un doble. Ahora quiero agregar los valores de las variables en la matriz de caracteres, pero no puedo encontrar una manera de hacerlo …
En mi programa principal, las variables deben tener estos tipos de datos y debe insertarse más tarde en la matriz de caracteres.
¿Alguien tiene una solución para este desafío?
Aquí hay un pequeño código de ejemplo:
int a = random(0, 100); double b = random(0, 100); char* myStrings[][6] = {"This is string 1", "This is string 2", "This is string 3", "This is string 4", "This is string 5", "This is string 6" }; void setup() { Serial.begin(9600); } void loop() { //now put the integer and double variables into the char array in the second column //Print the values for (int i = 0; i < 2; i++) { for (int j = 0; j < 6; j++) { Serial.print(myStrings[i][j]); Serial.print(" "); delay(100); } Serial.println(); } }
Muchas gracias de antemano.
Guss
EDITAR: El resultado debería verse así: Título (en este ejemplo es el texto «Esto es una cadena 1 «,» Esta es la cadena 2 «…) y luego los valores de las variables en la siguiente fila. Debería ser así:
This is String 1 This is String 2 This is String 3 Variable a Variable b Variable int Variable double Variable double Variable int
Comentarios
Respuesta
En primer lugar, debe decidir una estructura de datos para su tabla. Hay muchas opciones con varias ventajas y desventajas. Elijo una tabla asignada estáticamente aquí, con un ancho fijo para cada entrada en la tabla y un número fijo de columnas. También se pueden usar punteros a cadenas que están asignadas en el montón o en otro lugar, pero encuentro que esto es el más simple.
De todos modos, el problema básico no cambia: queremos escribir un valor entero en algún búfer de cadena. Estoy usando la función de biblioteca C snprintf()
aquí. Esta función es como printf()
, solo que escribe su salida en un búfer con un tamaño máximo dado. Por lo tanto, podemos usar cadenas de formato simple aquí y algunas soluciones para cadenas de formato que no funcionan ( puntos flotantes .. )
Aquí está el código.
#include <Arduino.h> /* A table is a 2 dimensional array of char buffers. The core element is a char buffer of fixed size. The number of columns must be fixed at compile time. Rows can by dynamically added in the structure without having to declare the number of elements. You can declare the number of rows at compile time, but do not need to fill them. Thus you can dynamically add rows to the table. */ #define MAX_ENTRY_SIZE 20 #define NUM_COLUMNS 3 #define COLUMN_PRINT_WIDTH MAX_ENTRY_SIZE char myTable[][NUM_COLUMNS][MAX_ENTRY_SIZE] = { {"Column 1", "Column 2" ,"Column 3"}, //Row 1 {"Variable a", "Variable b", "Variable int"}, //Row 2 {"Variable double", "Variable double" ,"Variable double"}, //Row 1 }; char* get_table_entry(int row, int column) { char* entry = myTable[row][column]; return entry; } void write_int_to_table(int value, int row, int column) { //Get a pointer to where the entry is char* entry = get_table_entry(row, column); //write a new string inside it snprintf(entry, MAX_ENTRY_SIZE, "%d", value); } void write_double_to_table(double value, int row, int column) { //Same as above, different format string.. char* entry = get_table_entry(row, column); //Formatting floats on an Arduino Uno is tricky. %f formatters don"t work (cut out due to size.) //use String API instead String stringFloat(value); const char* cString = stringFloat.c_str(); strncpy(entry, cString, MAX_ENTRY_SIZE); } void print_table() { //Get number of Rows int numRows = sizeof(myTable) / (MAX_ENTRY_SIZE * NUM_COLUMNS); for(int row = 0; row < numRows; row++) { //Print all columns of this row for(int column = 0; column < NUM_COLUMNS; column++) { char* entry = get_table_entry(row, column); Serial.print(entry); //fill with spaces to the right for(unsigned int i=0; i< COLUMN_PRINT_WIDTH - strlen(entry); i++) Serial.print(" "); } Serial.println(); //Table header seperator if(row == 0) Serial.println("============================================"); } } void setup() { Serial.begin(9600); print_table(); } void loop() { int a = random(0, 100); double b = random(0, 100); Serial.print("Will write new values for a = "); Serial.print(a); Serial.print(" and b = "); Serial.println(b); //write these in the second row (first row after header), first and second column. write_int_to_table(a, 1, 0); write_double_to_table(b, 1, 1); //Print table again print_table(); Serial.println(); Serial.println(); delay(5000); }
Dos rondas dan el resultado :
Column 1 Column 2 Column 3 ============================================ Variable a Variable b Variable int Variable double Variable double Variable double Will write new values for a = 7 and b = 49.00 Column 1 Column 2 Column 3 ============================================ 7 49.00 Variable int Variable double Variable double Variable double
Comentarios
- Vaya, muy impresionante. Muchas gracias por este código. Un pequeño pregunta, ¿cómo puedo imprimir el separador del cabezal de la mesa a la longitud del cabezal de la mesa automáticamente?
- Puede calcular el número de caracteres necesarios haciendo
int num = NUM_COLUMNS * MAX_ENTRY_SIZE
, luego imprima el carácter separador en unfor
bucle desde0
anum
.
snprintf()
. Además, su código de ejemplo falla porque accede a la memoria fuera de los límites de la matrizmyStrings
. ¿Puede dar un ejemplo de cómo debería verse la salida?