Re: Rückgabe von mehrdimensionalem String in C++

Sebastian Reinhardt <[email protected]>
Newsgroups gmane.user-groups.linux.dresden
Message-ID <[email protected]>
Am 02.05.22 um 08:58 schrieb Jeffrey Kelling:
> Hallo.
>
>>>      string elements[40][2]; // 2d string zum Speichern der Daten
> Stack arrays sind eher ein Überbleibsel aus C. Am Ende ist das ein Pointertyp,
> wenn du den zurückgibst, e.g.:
> ```
> auto f(...)
> {
>    string elements[40][2];
>    //...
>    return elements;
> }
> ```
> Dann gibt du einen Pointer auf eine lokale Variable zurück. Also einenen
> Pointer auf Speicher der nach dem Ende dieser Funktionier wieder freigegeben
> ist. (Der Compiler wird da auch warnen.)
>
> Wenn due Größe zur Compilierzeit bekannt ist, nimm std::array. In diesem Fall
> wäre das
> ```
> std::array<std::array<std::string, 2>, 40>
> ```
>
> Wenn du eine Datei einließt, ist es aber eher unwahrscheinlich, dass du die
> Größe vorher kennst. In dem Fall nimmst du std::vector, also:
>
> ```
> std::vector<std::vector<std::string>> rowCol;
>
> rwoCol.resize(40);
> for(auto & row: rowCol)
>     row.resize(2);
> ```
>
> Eine andere Möglichkeit wäre, einen flachen vector zu nehmen und selbst 2d zu
> adressieren:
> ```
> std::vector<std::string> arr;
> const int nRows = 40, nCols = 2;
> arr.resize(nRows * nCols);
>
> int row = 3, col = 1;
> arr[nCols*row + col] = "Hello"; // das wäre row-major
> ```
>
> Als Rückgabetyp schreibst du in jedem Fall jeweils den Typ hin als den du die
> zurückzugebende Varaible deklariert hast
>
> Es gibt leider noch keine matizen in der STL.
>
> Viele Grüße
>
> Jeffrey
>
>
>>> ----------
>>>
>>> Ich möchte nun die Variable "elements" zurückgeben.
>>> Ein "return elements" wirft mir nat. nur den Fehler:
>> Bist Du Dir sicher, dass Du das in C++ programmieren willst?
>> Ich denke Python oder Perl, oder wegen mir Javascript oder PHP
>> wären deutlich besser geeignet.
>>
>> Und ja, der C++ Compiler mag das nicht, wenn man den Return Typ als "void"
>> declariert und dann std::string[40][20] returned. Wobei das auch kein
>> "gute Idee" (TM) ist. Wenn es unbedingt C++ sein muss, nimm std::vector.
>>
>> Aber siehe oben... nimm ne andere Programmiersprache.
>>
>> Grüsse
>> Andreas
>
Hallo,

Danke schon mal für die Anregungen.

Thema: "Nimm 'ne andre Programmiersprache.." -> Klares: Jaein.

Ja, ich habe bisher viel mit Perl geschrieben, aber ich nutze die 
Gelegenheit mich doch mal in die C's einzuarbeiten. Also bleiben wir 
erstmal bei C++. Irgendwann muss ich mich ja mal damit befassen, um 
andere Programme ggf. zu erweitern usw., aber das ist dann schon wieder 
das nächste Thema.

Kleine Hintergrundinfo noch zu den Daten in der csv bzw. deren Verwendung:

Es sind Pinzurodnungen für 'ne "Himbeere". Dort steht z.B. 
"4;output;LCD_LED". Bedeutet, dass auf BCM4 ein Ausgang hängt und der 
die Hintergrundbeleuchtung einer Anzeige ein-/ausschalten kann.

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. Wenn ich also im Programm den GPIO 
ansteuern will, kann ich mit dem "value"=LCD_LED den "key"=4 in 
Funtkionen, wie etwa "gpioSetMode(4, PI_OUTPUT); " verwenden und eine 
Schleife darüber laufen lassen. Somit kann ich z.B. auch den LCD_LED- 
Ausgang auf einen anderen PIN legen, ohne das ganze Programm neu 
kompilieren zu müssen.

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;

};

auto READCSV::read_config_files(const string& csv_file_name)
{
     ifstream csv_in_file;

     string delimiter = ";";                   // Spaltentrenner
     vector <csv_values> elements;   // 2d string zum Speichern der Daten

//......

return elements;

}

--------

Das rufe ich dann mit folgender Zeile in der übergeordneten Funktion auf:

----------

//...

     READCSV read_csv;
     if (file_names[0].length() > 0)
         {
             auto pin_defs = read_csv.read_config_files(file_names[0]);
         }

//...

----------

Wirft aber (erwartungsgemäss) wieder nur 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: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

---------

Irgendwie steh ich noch auf dem Schlauch....

-- 
Mit freundlichen Grüßen

Sebastian Reinhardt


LMV
Landmaschinenvertrieb- und Service GmbH
Hauptstrasse 13G
(OT Hartmannsdorf)
01762 Hartmannsdorf- Reichenau

Geschäftsführer:        Sebastian Reinhardt
Amtsgericht:            Dresden
Handelsregisternummer:  HRB 2574
Umsatzsteuer- Identnr.: DE 140461622


Tel:  +49 373 26 1851
Mobil:+49 172 357 3107
Fax:  +49 373 26 86804
Mail: [email protected]
Web:  www.lmv-hartmannsdorf.de
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.