[C] Daten über Feldnamen zugreifen?

[C] Daten über Feldnamen zugreifen?

am 05.09.2006 22:38:56 von Thomas Barth

Hallo,
bisher rufe ich in C die Daten in etwa wie folgt ab:

MYSQL_RES *mysqlResult;
MYSQL_ROW mysqlRow;
MYSQL_FIELD *mysqlField;

char szQuery[STRLEN] = "";
unsigned int i;

snprintf(szQuery, STRLEN, "SELECT User, Host, Password FROM user");

mysql_real_query(hndMySQL, szQuery, strlen(szQuery));
mysqlResult = mysql_store_result(hndMySQL);

if (mysqlResult) {
if (0 < mysql_num_rows(mysqlResult)) {
while ((mysqlRow = mysql_fetch_row (mysqlResult)) != NULL) {
for(i = 0; i < mysql_num_fields(mysqlResult); i++){
mysqlField = mysql_fetch_field_direct(mysqlResult, i);
printf("%10s: %s\n", mysqlField->name, mysqlRow[i]);
}
}
}
mysql_free_result(mysqlResult);
}

Aber wie kann ich denn in C assoziativ auf die Werte zugreifen, wie es
z.B. in PHP möglich ist?

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
printf("User: %s, Host: %s", $row["User"], $row["Host"]);
}


Thomas B

Re: [C] Daten überFeldnamen zugreifen?

am 05.09.2006 22:53:35 von Norbert Melzer

Am Tue, 05 Sep 2006 22:38:56 +0200 schrieb Thomas Barth:

> Hallo,
> bisher rufe ich in C die Daten in etwa wie folgt ab:
>
> MYSQL_RES *mysqlResult;
> MYSQL_ROW mysqlRow;
> MYSQL_FIELD *mysqlField;
>
> char szQuery[STRLEN] = "";
> unsigned int i;
>
> snprintf(szQuery, STRLEN, "SELECT User, Host, Password FROM user");
>
> mysql_real_query(hndMySQL, szQuery, strlen(szQuery));
> mysqlResult = mysql_store_result(hndMySQL);
>
> if (mysqlResult) {
> if (0 < mysql_num_rows(mysqlResult)) {
> while ((mysqlRow = mysql_fetch_row (mysqlResult)) != NULL) {
> for(i = 0; i < mysql_num_fields(mysqlResult); i++){
> mysqlField = mysql_fetch_field_direct(mysqlResult, i);
> printf("%10s: %s\n", mysqlField->name, mysqlRow[i]);
> }
> }
> }
> mysql_free_result(mysqlResult);
> }
>
> Aber wie kann ich denn in C assoziativ auf die Werte zugreifen, wie es
> z.B. in PHP möglich ist?

C kennt keine Assoziativen Datentypen, aber diese Frage richtet sich
eher an die C-Kenner, daher TOFU, X-Post und F'Up2 dlcl
>
> while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
> printf("User: %s, Host: %s", $row["User"], $row["Host"]);
> }
>
>
> Thomas B

Re: [C] Daten überFeldnamen zugreifen?

am 06.09.2006 09:06:29 von Sven Paulus

Thomas Barth wrote:
> Aber wie kann ich denn in C assoziativ auf die Werte zugreifen, wie es
> z.B. in PHP möglich ist?

Mach doch einfach den kleinen Schwenk zu C++, dort hast Du in der STL
die maps, damit kannst Du dann bequem genau dies machen.

Alternativ bietet z.B. auch die glib
(http://developer.gnome.org/doc/API/glib/) Hash Tables, die sind
allerdings etwas aufwaendiger zu benutzen.

Und PS, dieses Posting ist weniger off-topic als die tausendste
Postgres-Antwort auf eine MySQL-Frage ...

Re: [C] Daten über Feldnamen zugreifen?

am 06.09.2006 11:26:51 von Claus Reibenstein

Norbert Melzer schrieb:

> Am Tue, 05 Sep 2006 22:38:56 +0200 schrieb Thomas Barth:
>
>> Hallo,
>> bisher rufe ich in C die Daten in etwa wie folgt ab:
>>
>> MYSQL_RES *mysqlResult;
>> [...]
>>
>> Aber wie kann ich denn in C assoziativ auf die Werte zugreifen, wie es
>> z.B. in PHP möglich ist?
>
> C kennt keine Assoziativen Datentypen, aber diese Frage richtet sich
> eher an die C-Kenner, daher TOFU, X-Post und F'Up2 dlcl

Welches TOFU? Ich sehe kein TOFU.

Die Frage hat nichts mit C zu tun, da - wie Du richtig bemerkst - C
keine assoziativen Datentypen kennt. Folglich ist die Lösung auch nicht
in der Sprache zu suchen, sondern in der verwendeten Programmbibliothek.
Das Posting ist hier in dclc daher vollkommen off topic.

Deshalb XP und Fup2 zurück.

Gruß. Claus

Re: [C] Daten überFeldnamen zugreifen?

am 06.09.2006 11:54:15 von Claudio Carobolante

Norbert Melzer schrieb:
> Am Tue, 05 Sep 2006 22:38:56 +0200 schrieb Thomas Barth:

>> bisher rufe ich in C die Daten in etwa wie folgt ab:
>>
>> MYSQL_RES *mysqlResult;
>> MYSQL_ROW mysqlRow;
>> MYSQL_FIELD *mysqlField;
[...]
>> Aber wie kann ich denn in C assoziativ auf die Werte zugreifen, wie es
>> z.B. in PHP möglich ist?
>
> C kennt keine Assoziativen Datentypen, aber diese Frage richtet sich
> eher an die C-Kenner, daher TOFU, X-Post und F'Up2 dlcl

Nein. C kennt keine assoziative Arrays und damit hört Das Thema für die
Gruppe dclc auch schon wieder auf. Alles Andere ist bitte in dcdm zu
klären.

X-Post und Fup zurück.

cc

Re: [C] Daten überFeldnamen zugreifen?

am 06.09.2006 13:47:07 von Thomas Rachel

Thomas Barth wrote:

> Hallo,
> bisher rufe ich in C die Daten in etwa wie folgt ab:

[...]

> Aber wie kann ich denn in C assoziativ auf die Werte zugreifen, wie es
> z.B. in PHP möglich ist?


Das geht nur indirekt, da, wie gesagt, C keine solchen Zugriff kennt. Da
müßtest Du Dir behelfsmäßig was basteln, nämlich alle Spaltennamen nach dem
(den) gesuchten Feldnamen durchsuchen und im Erfolgsfall den mitgeführten
Index auf die Zeilen anwenden.


Deine Vorgehensweise, bei jedem Schleifendurchlauf
mysql_num_fields(mysqlResult) und mysql_fetch_field_direct(mysqlResult, i)
aufzurufen, kommt mir ziemlich unperformant vor (ohne es jetzt wirklich
gemessen zu haben). Geschickter wäre es, einmal vor der Whileschleife

unsigned int numfields=mysql_num_fields(result);
MYSQL_FIELD* fieldinfo=mysql_fetch_fields(result);

stehen zu haben und in der Schleife dann an Stelle von

mysql_fetch_field_direct(mysqlResult, i)

einfach

fieldinfo[i]

zu verwenden. Oder sogar den Feldzugriff auchschon nach vorn zu ziehen, wie
im folgenden beschrieben:


Der von Dir gewünschte assoziative Zugriff könnte bspw. mit Hilfe der
Funktion

int spaltenindex(MYSQL_RES res, char * spaltenname)
{
unsigned int numfields=mysql_num_fields(result);
MYSQL_FIELD* fieldinfo=mysql_fetch_fields(result);
int i;
for (i=0; i if (strcmp(spaltenname,fieldinfo[i].name)==0)
return i;
}
return -1;
}

geschehen.

[NB: Dasselbe Problem formuliert als "Gegeben sei ein Array von structs,
welche ein Feld 'name' haben, sowie die Länge des Arrays. Wie finde ich den
Index des structs mit einem vorgegebenen String als 'name'?" wäre
zweifelsohne in dclc ontopic. Im Gesamtkontext gesehen gehört sie
allerdings eher hierher, da es konkret um MySQL und seine API-Datentypen
geht.]


Dann kannst Du

> mysqlResult = mysql_store_result(hndMySQL);
>
> if (mysqlResult) {

idField=spaltenindex(mysqlResult,"id");
assert(idfield >= 0);

schreiben und dann mit mysqlRow[idField] auf den entsprechenden Feldinhalt
zurückgreifen.

Die Abfrage

> if (0 < mysql_num_rows(mysqlResult)) {

ist übrigens überflüssig, denn

> while ((mysqlRow = mysql_fetch_row (mysqlResult)) != NULL) {

gibt bei einem leeren Result ohnehin direkt NULL zurück.


Thomas
--
>Ich bin anscheinend nicht so geschmacklos, ich habe meine Frau in
>de.talk.romance kennengelernt...
Man sagt "aus de.talk.romance gedownloaded". (K. Koehntopp in d.a.f.u)

Re: [C] Daten überFeldnamen zugreifen?

am 06.09.2006 13:56:36 von Thomas Rachel

Claus Reibenstein wrote:

>> eher an die C-Kenner, daher TOFU, X-Post und F'Up2 dlcl
>
> Welches TOFU? Ich sehe kein TOFU.

ACK.


> Die Frage hat nichts mit C zu tun, da - wie Du richtig bemerkst - C
> keine assoziativen Datentypen kennt.

....sondern man sie bei Bedarf mit Sprachmitteln simulieren muß -> IMHO
ontopic.


> Folglich ist die Lösung auch nicht in der Sprache zu suchen, sondern in
> der verwendeten Programmbibliothek.

Die ebenfalls keinen assoziativen Aufruf kennt, sondern lediglich ein Array
von structs mit Spalteninformationen liefert sowie die Länge des Arrays.


Man formuliere die Frage auf dclc-kompatible Art um:

Gegeben sei ein Array von structs, welche ein Feld 'name' haben, sowie die
Länge des Arrays. Wie finde ich den Index des structs mit einem
vorgegebenen String als 'name'?

Gegeben sei:
typedef struct {
[...]
char * name,
[...]
} MYSQL_FIELD;

Die Lösung lautet:


int spaltenindex(MYSQL_FIELD* fieldinfo, unsigned int numfields, char *
spaltenname)
{
int i;
for (i=0; i if (strcmp(spaltenname,fieldinfo[i].name)==0)
return i;
}
return -1;
}

IMHO ist das eine ganz klare C-Implementation des gegebenen Problems, ei
dessen ursprünglicher Angabe allerdings nicht alle benötigten Angaben
gemacht wurden.


Hier muß nun ein ganz klarer Cut gezogen werden, denn die Weiterentwicklung
dieser Funktion zur vom Aufruf her kompakteren

int spaltenindex(MYSQL_RES res, char * spaltenname)
{
unsigned int numfields=mysql_num_fields(result);
MYSQL_FIELD* fieldinfo=mysql_fetch_fields(result);
int i;
for (i=0; i if (strcmp(spaltenname,fieldinfo[i].name)==0)
return i;
}
return -1;
}

ergibt sich zwar fast zwangsläufig, verläßt aber wiederum den
Zuständigkeitsbereich von dclc.


> Das Posting ist hier in dclc daher vollkommen off topic.

Was den Aspekt des assoziativen Zugriffs angeht, durchaus nicht.


Dennoch bleibt das Problem im Kern MySQL-spezifisch, das C-Problem war nur
ein kleiner Teilaspekt des Ganzen. Den Fup2 setze ich daher nach dcdm.


Thomas

[Hoffentlich trifft der Spruch in meiner Sig gerade nicht zu...]
--
Unter Intuition versteht man die Fähigkeit gewisser Leute,
eine Lage in Sekundenschnelle falsch zu beurteilen.
(Friedrich Dürrenmatt)