MySQL result in Array schreiben und returnen



  • Hallo c++ community,

    ich möchte eine Funktion programmieren, die eine MySQL-Abfrage (immer die selbe Abfrage, und nur 1 Spalte) durchführt. Die abgerufenen Daten sollen dann per return in main() als array zur Verfügung stehen.

    Nun stehe ich als blutiger C-Anfänger vor dem Problem, dass in C keine arrays per return zurückgegeben werden können.

    Wie sieht das in der gängigen Praxis aus? Ist doch sicherlich keine Seltenheit, dass ein SQL-Result in einem Array zur Weiterverarbeitung landet.

    Die MySQL-API Doku hat leider nur ein sehr simples Beispiel mit sofortiger Verarbeitung per printf der Daten innerhalb der while-Scheife.

    Bin auf Eure Tipps gespannt!
    camelcase



  • Schreibe mal eben deine MySQL request Funktion hier rein, denke mal dann kann besser geholfen werden 😉



  • Hier ist das Programm in vereinfachter Form:

    #include <stdio.h> 
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include <curl/multi.h>
    #include <mysql.h>
    
    int main(void)
    {
    	char ** name;
    	getname(&name);
    
    	/* z.B. den vierten Namen ausgeben */
    	printf("%s\n",name[3]);
    }
    
    getname(char ** name) {
    	int x = 0;
    	MYSQL *conn;
    	MYSQL_RES *res;
    	MYSQL_ROW row;
    
    	*name = malloc(sizeof(char*)*10);
    
    	char *server = "localhost";
    	char *user = "username";
    	char *password = "password";
    	char *database = "database";
    
    	conn = mysql_init(NULL);
    
    	if (!mysql_real_connect(conn, server,
    		user, password, database, 0, NULL, 0)) {
    		fprintf(stderr, "%s\n", mysql_error(conn));
    		exit(1);
    	}
    
    	if (mysql_query(conn, "SELECT name FROM benutzer ORDER BY id LIMIT 10")) {
    		fprintf(stderr, "%s\n", mysql_error(conn));
    		exit(1);
    	}
    
    	res = mysql_use_result(conn);
    
    	while ((row = mysql_fetch_row(res)) != NULL){		
    		(*name)[x] = row[0];
    		x++;
    	}
    
       mysql_free_result(res);
       mysql_close(conn);
    
       return name;
    }
    

    Beim compilieren gibts dann folgende Meldungen:

    test.c: In function ‘getname’:
    test.c:57: warning: assignment makes integer from pointer without a cast
    test.c:64: warning: return makes integer from pointer without a cast
    


  • Lokale Arrays können nicht aus einer Funktion zurück gegeben werden, einer Funktion kann aber sehr wohl ein Array übergeben werden, das in dieser Funktion verändert wird. Oder die Funktion reserviert dynamisch Speicher und gibt einen Zeiger darauf zurück. Eine weitere Möglichkeit wäre die Übergabe eines Zeigers per "call by reference", also die Übergabe eines Zeigers auf den Zeiger.
    Beispiel:

    int f1(char* pArray, size_t len);
    char* f2();
    int f3(char** ppArray);
    ..
    char c[512];
    if(f1(c,512)) {..}
    ..
    char* c;
    c = f2();
    if(c)
    {
      ..
      free(c);
    }
    ..
    char* c;
    if(f3(&c))
    {
      if(c)
      {
        ..
        free(c);
      }
    }
    

    Eine Möglichkeit gibt es zusätzlich und wird häufig von der WinAPI verwendet. Man übergibt einen Nullzeiger und bekommt die Größe des benötigten Platzes zurück. Man kann nun den Speicher anfordern und die Funktion mit einem Zeiger darauf erneut aufrufen. Der Vorteil ist, dass Anforderung und Freigabe in der selben Funktion erfolgen:

    size_t f4(char* p)
    {
      if(!p)
      {
        // Platz berechnen
        return /* einen Wert */;
      }
      // andernfalls mit p arbeiten
    }
    ..
    size_t len;
    char* p;
    len = f4(0);
    p = malloc(len);
    if(p && f4(p))
    {
      ..
      free(p);
    }
    


  • Vicious Falcon schrieb:

    einer Funktion kann aber sehr wohl ein Array übergeben werden, das in dieser Funktion verändert wird

    Genau das habe ich ja vor (leider habe ich bei meinem vorhin geposteten Code das return am Ende zu entfernen vergessen, das noch von einem vorherigen Versuch stammte.

    Letztendlich geht es jetzt nur noch um die Meldung:

    assignment makes integer from pointer without a cast
    

    Was mag der compiler hier nicht?



  • Die Funktion erwartet die Adresse auf einen char*, du übergibst aber einen char***.

    Edit: Die Compilermeldung dürfte aber besagen, dass du keinen Returnwert angibst und per Default int eingesetzt wird.



  • .. schon gut ..



  • Vicious Falcon schrieb:

    .. schon gut ..

    Zu spät.
    🙂



  • Das bleibt doch unser Geheimnis, oder ( 😡 ) <- *rot werd*.
    Ich hätte vorher mal nachdenken sollen 🙂 .



  • Vicious Falcon schrieb:

    Das bleibt doch unser Geheimnis, oder ( 😡 ) <- *rot werd*.

    Aber klar. Ist aber nicht so schlimm, ich rede auch oft Blödsinn. Wahrscheinlich gehört das dazu.
    🙂



  • camelcase schrieb:

    (*name)[x] = row[0];
    

    dürfte wohl kaum da machen, was du erreichen willst.



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum C (C89 und C99) in das Forum Datenbanken verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Wutz schrieb:

    camelcase schrieb:

    (*name)[x] = row[0];
    

    dürfte wohl kaum da machen, was du erreichen willst.

    Da kannst du wohl Recht haben, Wutz.
    Wenn ich wüsste wie es richtig ist, würde ich die Frage hier auch nicht stellen. 🙄

    Trotz mehrfacher googelei bin ich noch nicht weiter. Ich komme einfach nicht dahinter, wo und wie ich das Array definieren muss, was dann in der getname-Funktion mit Daten gefüllt wird.

    Ist es denn so unüblich, das Abfragen einer Datenbank in eine Funktion zu packen, die ein Array befüllt und zur weiteren Verarbeitung an main zur Verfügung stellt? 😕 😕 😕


Anmelden zum Antworten