Ik wil tekst en getallen in een tabel afdrukken met Serial.print (); van een char-array. Mijn probleem is de conversie tussen de verschillende datatypes. Mijn idee is om de gegevens van de rijen in een for-lus af te drukken met de variabele i en de kolommen in een for-lus met de variabele j.
Ik heb in het volgende voorbeeld twee variabelen, een is het type integer en de tweede is een dubbel. Nu wil ik de waarden van de variabelen aan de char-array toevoegen, maar ik kan “geen manier vinden om dit te doen …
In mijn hoofdprogramma moeten de variabelen dit gegevenstype hebben en moet later in de char-array worden ingevoegd.
Heeft iemand een oplossing voor deze uitdaging?
Hier is een kleine voorbeeldcode:
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(); } }
Bij voorbaat hartelijk dank.
Guss
EDIT: De output zou er als volgt uit moeten zien: Headline (in dit voorbeeld is dit de tekst “This is string 1 “,” Dit is string 2 “…) en dan de waarden van de variabelen in de volgende rij. Het zou als volgt moeten zijn:
This is String 1 This is String 2 This is String 3 Variable a Variable b Variable int Variable double Variable double Variable int
Opmerkingen
Antwoord
Allereerst moet u beslissen voor een datastructuur voor uw tabel. Er zijn veel opties met verschillende voor- en nadelen. Ik kies hier een statisch toegewezen tabel, met een vaste breedte voor elk item in de tabel en een vast aantal kolommen. Men kan ook verwijzingen naar strings gebruiken die op de heap of elders zijn toegewezen, maar ik vind dit de eenvoudigste.
Hoe dan ook, het basisprobleem verandert niet: we willen een integerwaarde schrijven in een stringbuffer. Ik gebruik de C-bibliotheekfunctie snprintf()
hier. Deze functie lijkt op printf()
, alleen dat het de uitvoer naar een gegeven buffer met een maximale grootte. We kunnen hier dus eenvoudige format-strings gebruiken en enkele tijdelijke oplossingen voor niet-werkende format-strings ( zwevende punten .. )
Hier is de code.
#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); }
Twee rondes geven de uitvoer :
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
Reacties
- Wauw, zeer indrukwekkend. Heel erg bedankt voor deze code. Een kleine vraag, hoe kan ik de scheidingsteken voor de tafelkop automatisch afdrukken op de lengte van de tafelkop?
- U kunt het aantal benodigde tekens berekenen door
int num = NUM_COLUMNS * MAX_ENTRY_SIZE
en druk vervolgens het scheidingsteken af in eenfor
-lus van0
naarnum
.
snprintf()
. Ook uw voorbeeldcode crasht omdat u toegang krijgt tot geheugen buiten demyStrings
array. Kunt u een voorbeeld geven van hoe de uitvoer eruit zou moeten zien?