Chcę wydrukować tekst i liczby zmieszane w tabeli za pomocą Serial.print (); z tablicy znaków. Mój problem polega na konwersji między różnymi typami danych. Moim pomysłem jest wydrukowanie danych wierszy w pętli for ze zmienną i oraz kolumn w pętli for ze zmienną j.
W poniższym przykładzie mam dwie zmienne, jedna to liczba całkowita a druga jest podwójna. Teraz chcę dodać wartości zmiennych do tablicy znaków, ale nie mogę znaleźć sposobu, aby to zrobić …
W moim głównym programie zmienne muszą mieć te typy danych i należy wstawić później do tablicy znaków.
Czy ktoś ma rozwiązanie tego wyzwania?
Oto mały przykładowy kod:
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(); } }
Z góry wielkie dzięki.
Guss
EDYCJA: Wynik powinien wyglądać następująco: Nagłówek (w tym przykładzie jest to tekst „To jest ciąg 1 „,” To jest ciąg 2 „…), a następnie wartości zmiennych w następnym wierszu. Powinien wyglądać tak:
This is String 1 This is String 2 This is String 3 Variable a Variable b Variable int Variable double Variable double Variable int
Komentarze
Odpowiedź
Przede wszystkim powinieneś zdecydować się na strukturę danych dla swojego stołu. Istnieje wiele opcji, które mają różne zalety i wady. Wybieram tutaj statycznie przydzieloną tabelę ze stałą szerokością dla każdego wpisu w tabeli i stałą liczbą kolumn. Można również użyć wskaźników do łańcuchów, które są przydzielane na stercie lub w innym miejscu, ale uważam, że jest to najprostsze.
Tak czy inaczej, podstawowy problem się nie zmienia: chcemy zapisać wartość całkowitą w jakiś bufor ciągów. Używam tutaj funkcji biblioteki C snprintf()
. Ta funkcja jest jak printf()
, tylko zapisuje swoje dane wyjściowe do dany bufor o maksymalnym rozmiarze. Dlatego możemy tutaj użyć prostych ciągów formatujących i niektórych obejść dla niedziałających ciągów formatu ( zmiennoprzecinkowe .. )
Oto kod.
#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); }
Dwie rundy dają wynik :
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
Komentarze
- Wow, bardzo imponujące. Wielkie dzięki za ten kod. Jedno małe pytanie, jak mogę automatycznie wydrukować separator nagłówka tabeli do długości nagłówka tabeli?
- Liczbę potrzebnych znaków można obliczyć, wykonując
int num = NUM_COLUMNS * MAX_ENTRY_SIZE
, a następnie wydrukuj znak separatora w pętlifor
z0
do .
snprintf()
. Ponadto przykładowy kod ulega awarii, ponieważ uzyskujesz dostęp do pamięci poza granicami tablicymyStrings
. Czy możesz podać przykład, jak powinny wyglądać dane wyjściowe?