String als Rückgabewert einer int Funktion



  • ostringstream buffer; 
            buffer << ("%s", argv[i] ? argv[i] : "NULL");
    

    Was erwartest du dir von dem "%s" ?

    ---

    Zu deinem Callback: Sqlite ruft den Callback für jede Zeile auf, die zum Ergebnis gehört. Du kannst da natürlich keinen String zurückgeben denn laut Doku wird der Rückgabewert intern verwendet um die Query abzubrechen zu können:

    If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() routine returns SQLITE_ABORT without invoking the callback again and without running any subsequent SQL statements.

    Das heißt du musst es anders machen. Nahgeliegend wären globale Variablen und bei jedem Aufruf des Callbacks sicherst du das Ergebnis in einem globalen Container - zb std::vector.

    Globale Variablen sind aber hässlich. Deswegen bietet dir sqlite eine tolle Möglichkeit:

    [code="cpp"]int sqlite3_exec(
    sqlite3*, /* An open database /
    const char *sql, /* SQL to be evaluated /
    int (*callback)(void*,int,char
    ,char**), /* Callback function */
    *void , / 1st argument to callback /
    char **errmsg /* Error msg written here */
    );[/code]

    Der vierte Parameter wird dem Callback als ersten Parameter übergeben! Lösung für dein Problem: Du übergibst da einen Zeiger auf eine Datenstruktur, in der du deine Ergebnisse speichern möchtest. Im Callback speicherst du dann da, wo der Zeiger hinzeigt, deine Ergebnisse.

    ---

    Aber Allgemein:
    - Verbessere deine C++ Kenntnisse.
    - Lerne die Sqlite-API.



  • Ethon schrieb:

    ostringstream buffer; 
            buffer << ("%s", argv[i] ? argv[i] : "NULL");
    

    Was erwartest du dir von dem "%s" ?

    "%s" ist bereits als Beispiel seitens SQLite gegeben. Ich habe die Ausgabe lediglich in einen ostringstream umgeleitet/gespeichert.

    Der vierte Parameter wird dem Callback als ersten Parameter übergeben! Lösung für dein Problem: Du übergibst da einen Zeiger auf eine Datenstruktur, in der du deine Ergebnisse speichern möchtest. Im Callback speicherst du dann da, wo der Zeiger hinzeigt, deine Ergebnisse.

    Das bedeutet jetzt in meinem aktuellen Fall genau was?
    Welchen Zeiger muss ich jetzt in welcher Funktion definieren?
    Ich befürchte jetzt bin ich komplett verwirrt 😕

    Aber Allgemein:
    - Verbessere deine C++ Kenntnisse.
    - Lerne die Sqlite-API.

    Aye, aye! Bin Student und versuche mehr oder weniger den Funktionsumfang von C++ abzuarbeiten.

    Besten dank bisher schon mal.
    Bin dennoch über deine Antwort wie ich das nun im konkreten Fall besser machen kann gespannt.

    Gruß


  • Mod

    julianpe schrieb:

    Ethon schrieb:

    ostringstream buffer; 
            buffer << ("%s", argv[i] ? argv[i] : "NULL");
    

    Was erwartest du dir von dem "%s" ?

    "%s" ist bereits als Beispiel seitens SQLite gegeben. Ich habe die Ausgabe lediglich in einen ostringstream umgeleitet/gespeichert.

    In dem Beispiel stand aber doch sicher so etwas wie

    printf("%s", argv[i] ? argv[i] : "NULL");
    

    , oder? printf (oder eine seiner Varianten) ist eine C-Funktion, die zwar auch was mit Ausgabe zu tun hat, aber ganz anders funktioniert als du denkst. Das "%s" gehört nicht zur Ausgabe, das dient der Formatierung. Die die Streams mit dem Operator<< automatisch formatieren, wäre hier wohl eher folgendes gefragt:

    buffer << argv[i] ? argv[i] : "NULL";
    


  • SeppJ schrieb:

    julianpe schrieb:

    Ethon schrieb:

    ostringstream buffer; 
            buffer << ("%s", argv[i] ? argv[i] : "NULL");
    

    Was erwartest du dir von dem "%s" ?

    "%s" ist bereits als Beispiel seitens SQLite gegeben. Ich habe die Ausgabe lediglich in einen ostringstream umgeleitet/gespeichert.

    In dem Beispiel stand aber doch sicher so etwas wie

    printf("%s", argv[i] ? argv[i] : "NULL");
    

    , oder? printf (oder eine seiner Varianten) ist eine C-Funktion, die zwar auch was mit Ausgabe zu tun hat, aber ganz anders funktioniert als du denkst. Das "%s" gehört nicht zur Ausgabe, das dient der Formatierung. Die die Streams mit dem Operator<< automatisch formatieren, wäre hier wohl eher folgendes gefragt:

    buffer << argv[i] ? argv[i] : "NULL";
    

    Ja das stimmt. Es war vorher mit einem printf Befehl. Ich dachte das wäre eine einfache Ausgabe, daher habe ich auch den Befehl gegen cout bzw. gegen eine Umleitung in einen Stream genutzt.

    Nicht desto trotz bleibt die Problematik, wie ich möglichst einfach den Rückgabewert in einen string bekomme.



  • Wie würde die Funktion callback aussehen wenn ich die Rückgabewerte in einem Vector gespeichert werden?


  • Mod

    julianpe schrieb:

    Wie würde die Funktion callback aussehen wenn ich die Rückgabewerte in einem Vector gespeichert werden?

    Du schreibst einen Funktion

    int callback (void* foo, int, char**, char**)
    {
      vector<int> &vec = *reinterpret_cast<vector<int>*>(foo);
      // Schreib deine  Ergebnisse in vec
    }
    

    Dann machst du deinen sql-Aufruf:

    vector<int> results;
    sqlite3_exec(/*wasauchimmer*/, /*wasauchimmer*/, callback, reinterpret_cast<void*>(&results), /*wasauchimmer*/);
    

    Oder halt mit dem Datentyp, den du fuer angemessen haeltst. Das ist nicht nur fuer Ergebnisse gut, sondern kann auch genutzt werden, um zusaetzliche Parameter an den callback zu uebergeben,



  • Vielen Dank für deine Antwort und die Mühe,

    jedoch habe ich Probleme den Quellcode zu interpretieren, was der genau nun macht, und wie ich den Inhalt des Vektors später in der main.cpp ausgeben kann.

    Ich hätte gedacht, dass die Implementierung der SQlite3 Datenbank nicht so schwierig wird wie gedacht.

    Wie würde die Quellcodeimplementierung anhand meines o.g. Programms aussehen?

    Gruß
    Julian



  • julianpe schrieb:

    Ich hätte gedacht, dass die Implementierung der SQlite3 Datenbank nicht so schwierig wird wie gedacht.

    Davon abgesehen, daß du die Bedeutung des Wortes "Implementierung" nicht verstanden hast: Es wäre garnicht schwierig, wenn du nur die Sprache C++ in Grundzügen verstanden hättest.



  • Swordfish schrieb:

    julianpe schrieb:

    Ich hätte gedacht, dass die Implementierung der SQlite3 Datenbank nicht so schwierig wird wie gedacht.

    Davon abgesehen, daß du die Bedeutung des Wortes "Implementierung" nicht verstanden hast: Es wäre garnicht schwierig, wenn du nur die Sprache C++ in Grundzügen verstanden hättest.

    In Zukunft bitte ich hier um konstruktive Beiträge, die mir dem Threadersteller hilfreiche Lösungen beinhalten.
    Da ich mit C++ noch nicht sehr intensiv programmiert habe, kann man wohl davon ausgehen, dass nicht jeder der programmieren möchte 100% versiert ist.

    // Edit:
    Ich würde echt kein Thread erstellen und hier rumtippen aus lauter langerweile.
    Ich habe wirklich ein Problem das zu verstehen und diese Funktion zu nutzen. Jedoch sieht die Aufgabe es vor eine Datenbank in ein Programm einzubinden und dort Werte ein und auszulesen.



  • Dir wurde schon alles nötige gesagt. Solltest Du weitere Fragen haben empfehle ich davor Smart Questions zu lesen.


  • Mod

    Autoren externen Bibliothekn gehen normalerweise davon aus, dass man die Sprache beherrscht. Hier kommt verschaerfend hinzu, dass du eine C-Bibliothek benutzt. Du musst zur Benutzung also 3 Sprachen beherrschen:
    -C (und zwar objektorientiertes C, nicht das C wie im typischen Anfaengerlehrbuch!)
    -C++
    -SQL
    Sowie noch das wichtige Thema "Zusammenspiel von C und C++". Derzeit scheint dir davon alles zu fehlen (ausser vielleicht SQL, das kann ich nicht beurteilen), was erwartest du da? Da gibt es kein einfaches Kochrezept, das man einfach abschreiben kann. Wir koennen nur die Konzepte erklaeren, die hier wichtig sind, um die Sprachen richtig anzuwenden. Das haben wir versucht, aber du hast es nicht verstanden, weil du mit den Sprachen an sich noch Schwierigkeiten hast. Was sollen wir da noch tun? Dir das ganze Programm schreiben? Dir 99% des Programms schreiben und du ergaenzt noch "int main", damit du sagen kannst, du haettest es nicht komplett abgeschrieben? Die Antwort ist doch, dass du eben erst die Sprachen besser lernen musst, bevor du dieses Vorhaben angehen kannst. Denn auch wenn du es anders erwartest hast, ist es doch letztlich ein Fakt, dass die Benutzung einer externen C-Bibliothek keine einfache Sache ist.



  • Ich würde daher auch empfehlen gleich eine auf C++ portierte Version von SQLite zu benutzen, s.a. meinen Beitrag zu SQL unter C++ anwenden


Anmelden zum Antworten