Chci vytisknout text a čísla smíchaná v tabulce pomocí Serial.print (); z char pole. Mým problémem je převod mezi různými typy dat. Moje myšlenka je vytisknout data řádků ve smyčce for s proměnnou i a sloupců ve smyčce for s proměnnou j.
Mám v následujícím příkladu dvě proměnné, jedna je typ integer a druhá je dvojitá. Nyní chci přidat hodnoty proměnných do char-pole, ale nemohu najít způsob, jak to udělat …
V mém hlavním programu musí proměnné mít tyto datové typy a by měl být vložen později do pole char.
Má někdo řešení pro tuto výzvu?
Zde je malý ukázkový kód:
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(); } }
Mnohokrát předem děkuji.
Guss
EDIT: Výstup by měl vypadat takto: Nadpis (v tomto příkladu je to text „Toto je řetězec 1 „,“ Toto je řetězec 2 „…) a poté hodnoty proměnných v dalším řádku. Mělo by to být takto:
This is String 1 This is String 2 This is String 3 Variable a Variable b Variable int Variable double Variable double Variable int
Komentáře
Odpovědět
Nejprve byste se měli rozhodnout pro datovou strukturu tabulky. Existuje mnoho možností s různými výhodami a nevýhodami. Vybírám zde staticky přidělenou tabulku s pevnou šířkou pro každou položku v tabulce a pevným počtem sloupců. Jeden může také použít ukazatele na řetězce, které jsou přiděleny na haldě nebo jinde, ale považuji to za nejjednodušší.
Každopádně, základní problém se nezmění: Chceme zapsat celočíselnou hodnotu do nějaký řetězec vyrovnávací paměti. Používám zde funkci knihovny C snprintf()
. Tato funkce je podobná printf()
, jen když zapíše svůj výstup daný buffer maximální velikosti. Můžeme tedy použít jednoduché řetězce formátu zde a některá řešení pro řetězce nepracujícího formátu ( plovoucí body .. )
Tady je kód.
#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); }
Výstupem jsou dvě kola :
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
Komentáře
- Páni, velmi působivé. Děkuji mnohokrát za tento kód. Jedna malá otázka, jak mohu automaticky vytisknout oddělovač hlavy tabulky na délku hlavy tabulky?
- Počet potřebných znaků můžete vypočítat provedením
int num = NUM_COLUMNS * MAX_ENTRY_SIZE
, poté vytiskněte znak oddělovače vefor
smyčce od0
donum
.
snprintf()
. Také dojde k selhání ukázkového kódu, protože přistupujete k paměti mimo hranice polemyStrings
. Můžete uvést příklad toho, jak by měl výstup vypadat?