Pointer und Funktionen



  • Hallo zusammen,

    ich versuche gerade in meiner Freizeit ein wenig C/C++ zu lernen und habe mir dazu eine Aufgabe gesucht welche ich mit C++ lösen will.

    Jetzt bin ich aber auf ein Problem gestoßen, wo ich leider selber aktuell nicht weiter komme und frage daher hier nach Hilfe.

    Erstmal zu meiner Umgebung:
    * Linux
    * Eclipse oder VIM
    * g++
    * make

    Ich bin mir sicher das dies ein ganz einfaches Problem ist, aber ich komme einfach nicht darauf was genau ich falsch mache.
    Ich habe bisher nur Erfahrung in Scriptsprachen wie Perl, Python, Bash, Powershell.

    Zum lernen nutze ich "C++ von A bis Z von Jürgen Wolf" und das web.

    Das Problem selbst ist folgendes:

    Ich möchte einer Funktion (getBouquetURL) einen char pointer (bouquetURL) geben der in der Funktion mit einer nicht vorhersehbaren Menge an chars gefüllt wird.

    Hier mal ein Code snippet (kann sein das ich zuviel ausgeschnitten habe, falls ja einfach melden dann paste ich alles):

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <unistd.h>
    
    #include <jsoncpp/json/json.h>
    #include <curl/curl.h>
    #include <curl/easy.h>
    
    using namespace std;
    
    struct MemoryStruct {
       char *memory;
       size_t size;
    };
    
    int getBouquetURL(char *bouquet, char *json, char *bouquetURL);
    
    int getBouquetURL(char *bouquet, char *json, char *bouquetURL) {
       Json::Value root;
       Json::Reader reader;
    
       bool parsingSuccessful = reader.parse(json, root);
       if (!parsingSuccessful) {
          cerr << "Failed to parse JSON.\n" << reader.getFormattedErrorMessages() << endl;
          return(-1);
       }
    
       const Json::Value bouquets = root["bouquets"];
       for (unsigned int index = 0; index < bouquets.size(); ++index) {
          if (bouquets[index][1].asString() == bouquet) {
             cout << "Found bouquet url: " << bouquets[index][0].asString() << endl;
             const char *tempURL = bouquets[index][0].asCString();
             bouquetURL = (char *) &tempURL;
             break;
          }
       }
    
       return 0;
    }
    
    int main(int argc, char **argv) {
    
       int res = -1;
       char *bouquetURL = NULL;
       res = getBouquetURL(bouquet, jsonBouquets.memory, bouquetURL);
       cout << "debug bouquetURL: " << bouquetURL << endl;
       if (res != 0) {
          exit(2);
       }
    
       // Cleanup
       curl_easy_cleanup(curl);
    
       exit(0);
    }
    

    Wäre echt nett wenn mir jemand erklären könnte oder mir zumindest einen Hinweiss geben könnte was ich hier falsch mache.

    Danke und Gruß morlix



  • Hi,

    leider muss ich dir sagen, dass du ein weiteres Opfer von JW geworden bist.

    morlix schrieb:

    Wäre echt nett wenn mir jemand erklären könnte oder mir zumindest einen Hinweiss geben könnte was ich hier falsch mache.

    morlix schrieb:

    Zum lernen nutze ich "C++ von A bis Z von Jürgen Wolf" und das web.

    Ansonsten, was ist deine Frage, mein firefox findet nicht, wenn ich nach ? suche. 😛



  • ...



  • Danke erstmal für eure schnellen Antworten.

    Zum Thema JW: Ich werde mir dann wohl noch ein Buch aus den Empfehlungen des Forums kaufen.

    Ich wollte nicht die String Klasse verwenden, da ich später auch gerne bei anderen Projekten mitarbeiten würde und da werde ich eher C als C++ brauchen.

    Meine Frage war, wie ich es hin bekomme das in der Funktion getBouquetURL die gefundene Bouquet URL (bouquets[index][0].asCString();) in den an die Funktion getBouquetURL übergebenen char pointer (bouquetURL) geschrieben wird.

    So wie ich es mache bleibt der char pointer leer.
    Sprich ich sehe in eclipse keine Speicherreservierung und auch keinen Inhalt nach bouquetURL = (char 😉 &tempURL;

    @Swordfish:

    Ich habe mit diesen beiden Zeilen versucht den gefunden CString in meinen übergebenen char pointer zu schreiben. Die erste der beiden Zeilen hatte ich testweise eingefügt wegen dem cast von "char **" auf "char *".



  • morlix schrieb:

    Meine Frage war, wie ich es hin bekomme das in der Funktion getBouquetURL die gefundene Bouquet URL (bouquets[index][0].asCString();) in den an die Funktion getBouquetURL übergebenen char pointer (bouquetURL) geschrieben wird.

    Du hast hier überall lokale Variablen (bouquets, bouquetURL, etc). Das geht so nicht. Die sind nach Ablauf deiner Funktion tot. Du musst das, was bouquets[index][0].asCString() zurückgibt, kopieren. Leichter gesagt als getan. Du musst du größe des Strings wissen. Ist die größe konstant, dann ok, ist sie dynamisch dann ist das schonmal doof. Ich weiß nicht, wie man das schön in C macht. Damit will ich dir auch gleich sagen, du solltest dich für eine Sprache entscheiden. C ist nicht C++. Ein Apfel ist keine Birne. Es sind 2 völlig verschiedene Sprachen, die man auf keinen Fall mischen soll/darf.
    Außerdem ist es auch keine gute Idee, das const bei const char* wegzucasten. Das const ist bestimmt nicht zum Spaß da. Achso ja, und abschließend mein Rat: std::string. :p



  • ...



  • Swordfish schrieb:

    reinterpret_cast<>() , was einem C-Style-Cast gleichkommt.

    Hinter einem C-Cast kann wirklich alles stecken, nicht nur ein reinterpret_cast .



  • out schrieb:

    Swordfish schrieb:

    reinterpret_cast<>() , was einem C-Style-Cast gleichkommt.

    Hinter einem C-Cast kann wirklich alles stecken, nicht nur ein reinterpret_cast .

    Ne, hinter einem C-Cast kann wirklich alles stecken (double*)(int*)0 ist nur mit reinterpret_cast<> abbildbar (oder 2 static_casts<>).

    Aber reinterpret_cast<> mit C-Style-Cast gleichsetzen ist mehr als nur irreführend.



  • ...



  • Swordfish schrieb:

    Es ist ein sehr, sehr ähnlicher Holzhammer ...

    Nein, hinter einem reinterpret_cast<> verbirgt sich NIE ein Funktionsaufruf.
    Hinter einem C-Style-Cast sehr wohl.



  • ...



  • #include <string>
    
    int main() {
      std::string s;
    
      (std::string) s;                  // OK
      static_cast<std::string>(s);      // OK
      reinterpret_cast<std::string>(s); // Compilerfehler.
    }
    

    reinterpret_cast ist ziemlich beschränkt und kommt insofern einem C-Style-Cast beim besten Willen nicht gleich. Es ist allerdings richtig, dass die Funktionalität, die reinterpret_cast abdeckt, leicht versehentlich zu missbrauchen ist -- Casts zwischen unverwandten Typen werden möglich, Casts zwischen verwandten Typen müssen nicht immer gültige Ergebnisse liefern, und der Compiler muss es anstandslos schlucken, weil du ihm gerade mit der Cast-Keule auf den Kopf geschlagen und ihn angeschrien hast, dass du schon wüsstest, was du tust. Insofern ist eine gewisse Ähnlichkeit zu C-Casts vorhanden, auch wenn C- und Reinterpret-Casts mitunter unterschiedliche Ergebnisse liefern können, wenn beide im selben Kontext kompilierbar sind. (Ich denke da an Mehrfachvererbung.)

    Übrigens kann ein reinterpret_cast durchaus Berechnungen auf dem Eingabewert veranlassen (das behält der Standard sich in 5.2.10 (3) ausdrücklich vor):

    ISO/IEC 14882:2011 5.2.10 (3) schrieb:

    3 [ Note: The mapping performed by reinterpret_cast might, or might not, produce a representation different from the original value. — end note ]

    Ihr habt also beide Unrecht. :p



  • seldon schrieb:

    [...] der Compiler muss es anstandslos schlucken, weil du ihm gerade mit der Cast-Keule auf den Kopf geschlagen und ihn angeschrien hast, dass du schon wüsstest, was du tust. [...]

    Swordfish schrieb:

    [...] Es ist ein sehr, sehr ähnlicher Holzhammer ...

    👍 🤡



  • morlix schrieb:

    Ich wollte nicht die String Klasse verwenden, da ich später auch gerne bei anderen Projekten mitarbeiten würde und da werde ich eher C als C++ brauchen.

    Dann solltest du lieber gleich C lernen. "Vernünftiges" C++ hat mit C nur noch sehr wenig zu tun.



  • morlix schrieb:

    ich versuche gerade in meiner Freizeit ein wenig C/C++ zu lernen

    Sowas gibt es nicht. Außer als Spottausdruck für das, was ein gewisser Autor verbricht.

    morlix schrieb:

    Zum lernen nutze ich "C++ von A bis Z von Jürgen Wolf" und das web.

    Ebendieser. Du wurdest gewolft. Leider Pech gehabt. Das wieder loszuwerden, wird viel länger dauern, als es zu lernen.



  • Habe gerade C++ Der Programmierer und C++ Primer bestellt und werde versuchen alles von JW zu vergessen.

    Was meinst du mit so etwas wie C/C++ in seiner Freizeit zu lernen gibt es nicht?



  • ...



  • morlix schrieb:

    Habe gerade C++ Der Programmierer und C++ Primer bestellt und werde versuchen alles von JW zu vergessen.

    Was meinst du mit so etwas wie C/C++ in seiner Freizeit zu lernen gibt es nicht?

    Es gibt keine Sprache namens C/C++. Sie haben sich inzwischen unglaublich weit entfernt. Dein C/C++-Code macht einem sofort Bauchweh und Kopfweh und dann, wenn man in der main() ist und alles überstanden zu haben meint, und das exit() sieht, da möchte man sterben.


Anmelden zum Antworten