Am 02.05.22 um 21:58 schrieb Jeffrey Kelling:
Hallo.
Nun kenn ich aus Perl die Vorzüge von "Hashes". Darin lassen sich sehr gut diese Informationen speichern und mit den "keys" die "values" oder mit den "values" die "Keys" abrufen.
Eine Hasmap ha die STL auch: https://en.cppreference.com/w/cpp/container/unordered_map
D.h. auch, dass ich nat. weiss, wie groß der Datenraum max. ist. Hier: 40-Pins -> 40-Werte (abzügl. 3,3V, 5V, GND-Pins usw.). Ein dynamisch angepasster Vector ist nat. wahrscheinlich sinnvoller. Vectoren habe ich auch schon im Code und habe mir mal angesehen, wie man eigene "Struct"'s anlegt. Kommt den Perl-Hashes schon sehr nahe.
Ich habe das jetzt so angelegt:
struct csv_values { string pin_number; string in_out_name; string in_out_function;
};
Es ist durchaus sinnvoll das was du über die Datan/Domäne weißt in Code zu gießen.
make
g++ -c -o src/lib/init_hw.o src/lib/init_hw.cpp src/lib/init_hw.cpp:In member function ‘void ZEROHW::init_hw(const std::vector<std::__cxx11::basic_string<char> >&)’: src/lib/init_hw.cpp:52:69:error: use of ‘auto READCSV::read_config_files(const string&)’ before deduction of ‘auto’ 52 | auto pin_defs = read_csv.read_config_files(file_names[0]); | ^ make: *** [<eingebaut>: src/lib/init_hw.o] Fehler 1
Hast du vllt die Funktion mit `auto` Rückgabetyp in einem Header nur deklariert, aber nicht definiert? `auto` geht nur, wenn der Compiler beim Aufruf auch sieht was in der Funktion zurückgegeben wird, wenn sie als auf irgendeineweise inline bzw. in der gleichen Kompiliereinheit definiert wird. Wenn die Definition in einer separaten Einiheit ist, dann musst du explizit sagen was der Rückgabetyp ist, also `std::vector<csv_values>`.
Viele Grüße
Jeffrey
Hallo,
Danke für den Hinweis auf die "unordered map". Das was ich bisher mit der Suche nach "C++ Hash" gefunden habe, funktioniert anders, als eine Hash-Variable in Perl. Die von Dir verlinkte "unordered map" ist da eher das Richtige. Allerdings gefällt mir der "Vector" mit der Möglichkeit eine eigene Struktur zu definieren auch sehr gut. Ich kann damit genau das machen, was ich will (hoffe ich), d.h in dem später aufgerufenen Code möchte ich erstmal über alles, was mit "Output" bezeichnet ist (z.B.: "4;output_1;LCD_LED"), den GPIO richtig mit "gpioSetMode(OUTPUT_1, PI_OUTPUT);" usw. setzen (dafür benötige ich die Pin-Mummer) und in den eigentlichen Programmteilen (Messen und Regeln) eben z.B. immer "gpioWrite(LCD_LED, 1)" oder "gpioWrite(LCD_LED, 0)" zum Ein-/Ausschalten nutzen. Das sollte mit dem Vector machbar sein.
Ok, da ich nicht sinnlos zwischen den Techniken hin und her wechseln möchte, habe ich mich auf den Vector festgelegt. Außerdem habe ich auch noch mal hier [1] nachgeschaut, wie das mit den Referenzen funktioniert, da ich diese ja z.B. auch schon zum Übertragen des Dateinamens verwende. Nur klappt es noch nicht mit der Rückgabe des Vectors.
In der Lesefunktion habe ich das folgendermaßen definiert/ geschrieben:
------ read_csv.cpp -----------
#include "../headers/read_config_files.hpp" using namespace std; struct csv_values { string pin_number; string in_out_name; string in_out_function;
};
void read_config_files (const std::string& csv_file_name, vector<csv_values>& elements) {
//....
------ read_csv.cpp -----------
Die zugehörige Headerdatei:
------ read_config_files.hpp -----------
#ifndef READ_FILES_H #define READ_FILES_H using namespace std;
class READCSV { private: struct csv_values { string pin_number; string in_out_name; string in_out_function; };
public: void read_config_files (const std::string& csv_file_name, vector<csv_values>& elements); }; #endif
------ read_config_files.hpp -----------
Aufgerufen wird das aus:
------ init_hw.cpp -----------
#include "../headers/init_hw.hpp" #include "../headers/read_config_files.hpp"
using namespace std;
struct csv_values { string pin_number; string in_out_name; string in_out_function; };
void ZEROHW::init_hw(const std::vector<string> &file_names) { READCSV read_csv; vector<csv_values> elements; if (file_names[3].length() < 0) { read_csv.read_config_files(file_names[0], elements); }
//...
------ init_hw.cpp -----------
und die Headerdatei:
------ init_hw.hpp -----------
#ifndef INITHW_H #define INITHW_H using namespace std; class ZEROHW { private:
public: void init_hw(const std::vector<string> &file_names); void set_gpio(); }; #endif
------ init_hw.hpp -----------
Wenn ich das nun versuche zu Kompilieren, kommt ein Fehler:
------------------
make g++ -c -o src/lib/init_hw.o src/lib/init_hw.cpp src/lib/init_hw.cpp:In member function ‘void ZEROHW::init_hw(const std::vector<std::__cxx11::basic_string<char> >&)’: src/lib/init_hw.cpp:52:54:error: cannot convert ‘std::vector<csv_values>’ to ‘std::vectorREADCSV::csv_values&’ 52 | read_csv.read_config_files(file_names[0], elements); | ^~~~~~~~ | | | std::vector<csv_values> In file included from src/lib/init_hw.cpp:33: src/lib/../headers/read_config_files.hpp:28:91:note: initializing argument 2 of ‘void READCSV::read_config_files(const string&, std::vectorREADCSV::csv_values&)’ 28 | void read_config_files (const std::string& csv_file_name, vector<csv_values>& elements); | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~ make: *** [<eingebaut>: src/lib/init_hw.o] Fehler 1
------------------
Was ich nicht verstehe ist, warum er aus "std::vector<csv_values>" nun ‘std::vectorREADCSV::csv_values&' macht bzw. wo das Problem liegt.
Ich habe auch schon mit "read_config_files(file_names[0], elements);" statt "read_csv.read_config_files(file_names[0], elements);" versucht. Aber dann kommt nat. erwartungsgemäß, dass die Funktion "read_config_files" nicht definiert/ deklariert ist.
Was nun? Wo liegt mein Fehler? Fehlt noch was?
----
Links:
[1] https://www.educba.com/c-plus-plus-pass-by-reference/