Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Anfängerfrage: Nochmal zum Verständnis

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
14.06.2018, 13:20 Uhr
Getit



Ich hatte bereits gefragt, warum ich diese Funktion


C++:
bool process(const std::vector<std::string>& args) {
...
}



Nur so

C++:
int main(int argc, char* argv[]) {
  ...
  process({{argv + 1, argv + argc}});    //korrekt
  ...
}


aufrufen kann.

Und das hier

C++:
process({argv + 1});


oder das hier

C++:
process({argv + 1, ""});


fehlschlägt.

FloSoft hat mir erklärt, dass argv eben kein string ist - Pointer auf char[].
Und ao dass anhand der Initialisierungsliste {} ein String Objekt erzeugt wird.

Jetzt habe ich auf cplusplus.com eine Referenz gefunden.
Für String gibt es die folgenden Konstruktoren:

C++:
string();  //1
string (const string& str); //2
tring (const string& str, size_t pos, size_t len = npos); //3
string (const char* s);  //4
string (const char* s, size_t n);  //5
string (size_t n, char c);  //6
template <class InputIterator>                          //7
  string  (InputIterator first, InputIterator last);  //7


Die Konstruktoren 1,2,3,4 scheiden aus - die Anzahl der Argumente passt nicht.
Die Konstruktoren 5,6 scheiden aus - wir haben zwei char* in der Initialisungsliste.

D.h. der Konstruktor 7

C++:
template <class InputIterator>                          
string  (InputIterator first, InputIterator last);  


kommt zum Zuge.
Richtig???

Wie kann ich am Besten vorgehen, um mir bei so etwas Klarheit zu verschaffen??
Mir würde da z.B. in den Sinn kommen, eine Klasse 'myString' zu schreiben, die von String erbt; dann alle Konstruktoren in diese Klasse 'myString' zu schreiben und im Debugger zu schauen welcher Konstruktor verwendet wird.

Dieser Post wurde am 14.06.2018 um 13:21 Uhr von Getit editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
24.07.2018, 18:07 Uhr
win8789



Der Fehler ist, dass die Funktion "process" keinen String sondern einen Vector als Parameter übergeben bekommt.

der Aufruf


C++:
process({{argv + 1, argv + argc}});    //korrekt



erzeugt also einen Vector.

Ein Vector besitzt die Konstruktoren:


C++:
default (1)    explicit vector (const allocator_type& alloc = allocator_type());

fill (2)     explicit vector (size_type n, const value_type& val = value_type(),
                 const allocator_type& alloc = allocator_type());

range (3) template <class InputIterator>
         vector (InputIterator first, InputIterator last,
                 const allocator_type& alloc = allocator_type());

copy (4) vector (const vector& x);
//Quelle: www.cplusplus.com/reference/vector/vector/vector/



In diesem Fall ist der dritte Konstruktor relevant, da er zwei Iteratoren (Objekt, welches sehr stark mit einem Pointer verwandt sind) übergeben bekommt.

Die Variable char* argv[] ist eigentlich ein Array, welcher aus Pointern besteht, welche auf C-Strings verweisen (C-String bestehend aus chars und enden mit '\0').
Jetzt kommt Zeigerarithmetik ins Spiel. Die Variable argv ist nämlich auch ein Pointer, welcher auf den Anfang des ersten C-Strings zeigt. Durch "argv + 1" schiebt man den Pointer auf den Anfang des zweiten C-Strings. Durch "argv + 2" schiebt man den Pointer auf den Anfang des dritten C-Strings, usw.


Wenn wir das Programm mit den Befehl "name.exe test1 test2" ausführen hat argv folgende Werte:

argv[0] = "name.exe" //das erste Element von argv ist immer der Name des Programms
argv[1] = "test1"
argv[2] = "test2"

Der dritte Konstruktor eine Vektors wird mit den Worten:
"Constructs a container with as many elements as the range [first,last), with each element constructed from its corresponding element in that range, in the same order." beschrieben. Das heißt, dass er die Elemente in den Vectoren einfügt, welche sich zwischen den ersten und den zweiten Pointer (bwz. Iteratoren) befinden. Jedoch nicht das Element auf welchen der zweite Pointer verweist.

D.h., dass ein Aufruf wie "vector<string> content({argv+1,argv+argc})" erzeugt einen Vector mit den Werten:

content[0] = "test1"
content[1] = "test2"

Hier ist nochmal ein kleines Programm welches dies verdeutlicht:


C++:
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main(int argc, char* argv[]){
    
    cout << "argc: " << argc << endl; //Anzahl an Elemente in argv
    
    for(int i = 0; i < argc; i++){ //Gib alle Elemente aus in argv
        cout << "argv "<< i <<  " : " << argv[i] << endl;
    }cout << endl;
    
    
    vector<string> content({argv+1,argv+argc}); //Erstelle einen Vector, welcher die Elementen argv[1] bis argv[argc-1] hat.
    for(int i = 0; i < content.size(); i++){
        cout << "string " << i <<  " : " << content[i] << endl;
    }cout << endl;
}



Ruf das Programm einfach mal über die Konsole mit verschiedenen Parametern auf.

Dieser Post wurde am 24.07.2018 um 18:51 Uhr von win8789 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
24.07.2018, 18:38 Uhr
Getit



Danke!!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: