Unzulässige Zeigeraddition beim Aufruf von Tquery->Open()



  • TDateTime* myDate = new TDateTime();
    String myDateString = myDate->CurrentDate();
    int monthPos =  myDateString.Pos(".");
    int month = myDateString.SubString(monthPos+1,2).ToInt();
    String jahr = myDateString.SubString(7,4);
    
    gridtable *grid = new gridtable(StringGrid1, ADOQuery1);
    grid->filltable("select * from konto where monat='"+month+"' and jahr='"+jahr+"'");
    

    Ich habe folgenden Quelltext und bekomme vom Compiler beim Linken den Fehler, dass in der letzten Zeile eine unzulässige Zeigeraddition durchgeführt würde.

    Ich benutze an der STelle erstens keine Addition und zweitens keinen Zeiger oder irre ich mich?

    Kann mir da jemand sagen wo der Fehler hängt?
    Die ANweisung filltable() erwartet einen sql-String als Argument



  • Du versuchst offensichtlich sehr wohl zwei Pointer zu addieren...
    Schau dir mal dieses Beispiel an:

    std::string str;
    //str = "str1" + "str2"; // error C2110: '+' : cannot add two pointers
    str = std::string("str1") + std::string("str2"); // Funktioniert
    str = (std::string)"str1" + (std::string)"str"; // Funktioniert ebenfalls
    

    Darüber hinaus ist die Variable "month" in deinem Code vom Typ int was vermutlich der Hauptverursacher deines Problems ist.



  • Es gibt keinen sql-String. Vermutlich meist Du AnsiString.

    Was sind denn month und jahr denn nun in der Datenbank. Deinem SELECT nach sind es Zeichenketten und keine Integerwerte. Wenn es Zeichenketten sind, verwende bessser die Funktion QuotedStr() um die Hochkommas um die Strings zu erzeugen. Oder verwende Escape-Sequenzen um die Hochkommas einzufügen, aber das Problem ist tatsächlich der Mischmasch aus Auführungszeichen und Hochkommas.

    Wenn es in der Datenbank Integerwerte sind, musst Du die Hochkommas sowieso weglassen. Dann aber noch der Hinweis auf TDateTime::DecodeDate().



  • in der Datenbank sind diese zwei Felder integer-Felder.
    Ich haeb die einfachen Anführungszeichen erst nicht drin gehabt, da hat der genörgelt, also habe ich sie reingenommen und der Fehler war immernoch da.

    Dass month und jahr jeweils integer sind, ist schon so gewollt.
    Sollen ja eins zu eins mit der Datenbank vergleichen werden. Da kann ich ja net integer mit string vergleichen.

    @Just: werde dein Beispiel mal auf mein Problem umbauen und testen obs dnan läuft 🙂



  • Hallo

    TDateTime myDate = Date();
    unsigned short year;
    unsigned short month;
    unsigned short day;
    myDate.DecodeDate(&day, &month, &day); 
    
    gridtable *grid = new gridtable(StringGrid1, ADOQuery1);
    grid->filltable("select * from konto where monat='"+ IntToStr(month)+"' and jahr='"+IntToStr(jahr)+"'");
    

    Wenn die beiden Felder in der Datenbank wirklich vom Typ integer sind, brauchst du die Hochkommas in der SQL-Anweisung nicht. Jedenfalls kann ein solcher Fehler sich erst zur Laufzeit auswirken, während du ja offenbar nicht mal compilierbaren Code hattest.

    bis bald
    akari



  • Läuft doch nicht so wie geplant.

    IntToStr geht hier in dem Fall nicht, da in der DB Integer drin stehen.
    Ohne die Funktion und ohne Hochkommas komtm wieder unzulässige Zeigeraddition.

    @Just: dein beispiel funktioniert nicht, da es keine Funktion std::string gibt.



  • *bump*



  • Padde85 schrieb:

    @Just: dein beispiel funktioniert nicht, da es keine Funktion std::string gibt.

    std::string ist ja auch keineswegs eine Funktion, sondern viel mehr ein Container der STL.
    Mein Beispielcode sollte außerdem lediglich zeigen, wie so ein "cannot add two pointers" Error im Normalfall zustande kommt,
    was dir wiederum helfen hätte sollen, dein Problem eigenständig zu lösen.
    Da du ja aber offensichtlich noch nichtmal Funktionen von Datentypen unterscheiden kannst, war das wohl ein wenig zu viel verlangt.
    Um nochmal zu std::string zurückzukommen; du musst den Header <string> includen, damit std::string definiert ist.
    Und was nun wieder dein eigentliches Problem angeht, schätze ich mal, dass (speziell die letzte Zeile) es ungefähr so aussehen muss, damit du den Code kompilieren kannst:

    TDateTime* myDate = new TDateTime();
    String myDateString = myDate->CurrentDate();
    int monthPos =  myDateString.Pos(".");
    int month = myDateString.SubString(monthPos+1,2).ToInt();
    String jahr = myDateString.SubString(7,4);
    
    gridtable *grid = new gridtable(StringGrid1, ADOQuery1); 
    
    grid->filltable( "select * from konto where monat='" + IntToStr(month) + "' and jahr='" + jahr + "'" );
    


  • du wirfst mir vor nicht Funktion von Datentyp unterscheiden zu können, dann muss ich dir leider vorwerfen, nicht lesen zu können.

    Habe schon drei oder vier Mal geschrieben, dass in der Datenbank Integer stehen und nicht Strings.

    So ein geflame ist hier glaueb ich unnötig. Auf der sachlichen Ebene kommen wier hier schneller voran



  • Hallo

    Padde85 schrieb:

    Läuft doch nicht so wie geplant.

    "Läuft nicht" ist keine ausreichende Fehlerbeschreibung!

    IntToStr geht hier in dem Fall nicht, da in der DB Integer drin stehen.
    

    IntToStr hat gar nichts mit Datenbank-Datentypen zu tun! Selbstverständlich muß zur Laufzeit dein Programm alle Integers in Strings umwandeln um den Abfrage-String zusammenzubauen. Dieser String wird komplett an die Datenbank übergeben, die den String wieder parst und selber in die richtigen Datentypen komvertiert.

    Ohne die Funktion und ohne Hochkommas komtm wieder unzulässige Zeigeraddition.
    

    😕

    bis bald
    akari



  • Wie auch schon akari festgestellt hat geht es bis jetzt in diesem Thread in keinem Fall um die Datenbank selbst:

    akari schrieb:

    Jedenfalls kann ein solcher Fehler sich erst zur Laufzeit auswirken, während du ja offenbar nicht mal compilierbaren Code hattest.

    Dein Problem war bis jetzt immer, dass du deinen Code nicht einmal kompilieren konntest.
    Dass du Datentypen nicht von Funktionen unterscheiden kannst, ist leider traurige Realität, sorry:

    Padde85 schrieb:

    @Just: dein beispiel funktioniert nicht, da es keine Funktion std::string gibt.

    Es tut mir Leid wenn du das zu persönlich genommen hast, war eigentlich nur rein objektiv und sachlich gemeint.

    Um dir weiterhelfen zukönnen, wäre es vielleicht sinnvoll, wenn du uns auch einmal mitteilen würdest, was denn jetzt die filltable() Methode aus deiner gridtable Klasse eigentlich für einen Parameter erwartet.

    Ist es ein String? Oder vielleicht doch ein Integer?
    Ich persönlich tippe auf String, da es anderenfalls wenig Sinn machen würde.

    Falls die Funktion wirklich auch einen String erwartet, musst du ihr auch Strings übergeben, KEINE Integer.

    Das Umwandeln/Parsen des an die Datenbank geschickten Strings erfolgt dann Datenbankintern und ganz von selbst.



  • Hallo

    Ach übrigens ist std::string hier in der Tat nicht angebracht, da die Borland-VCL einen eigenen Datentyp (Ansi)-String hat, der einerseits nicht direkt kompatibel zu std::string ist und anderseits aber alle notwendigen Operation (IntToStr) bequemer bereit stellt als std::string.

    bis bald
    akari



  • Jo, das is klar akari.
    Das Beispiel sollte ja auch nur zeigen wie so ein "cannot add two pointers" Error im Normalfall entsteht.

    Ich hab ihm ja dann auch schon ein zweites Codebeispiel auf sein Programm bezogen gezeigt, welches doch eigentlich kompilierbar sein sollte, wenn seine bisherigen Angaben korrekt waren.



  • ich stelle nachher nochmal den Code hier rein, wenn ich zu Hause bin.

    Sowohl den, den ich hier schon gepostet habe als auch den, der die Methode filltable enthält.

    Gelöst, bzw lösen wollen habe ich das bisher mit dem Code-Beispiel von akari.



  • so hier nochmal der Code:

    Datei mit main-Methode:

    #include <vcl.h>
    #pragma hdrstop
    
    #include "buchhaltung.h"
    #include "gridtable.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm2 *Form2;
    String monate[12] = {"Januar","Februar","März","April","Mai","Juni","Juli",
    				 "August","September","Oktober","November","Dezember"};
    //---------------------------------------------------------------------------
    __fastcall TForm2::TForm2(TComponent* Owner)
    	: TForm(Owner)
    {
    	TDateTime myDate = Date();
    	unsigned short year;
    	unsigned short month;
    	unsigned short day;
    	myDate.DecodeDate(&day, &month, &day);
    
    	lab_showdat->Caption="Kontoübersicht für "+monate[month-1]+" "+year;
    	StringGrid1->Cells[0][0]="Einnahmen";
    	StringGrid1->Cells[1][0]="Betrag";
    	StringGrid1->Cells[2][0]="Ausgaben";
    	StringGrid1->Cells[3][0]="Betrag";
    
    	gridtable *grid = new gridtable(StringGrid1, ADOQuery1);
    	grid->filltable("select * from konto where monat="+IntToStr(month)+" and jahr="+IntToStr(year));
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm2::close(TObject *Sender)
    {
    	ADOQuery1->Active=false;
    	Close();
    }
    

    und hier die Definition der filltable-Methode:

    void __fastcall gridtable::filltable(String sql)
    {
    int i=1;
    int ie=1, ia=1;
    getData(sql);
    int zeilen = _query->RecordCount;
    while(i<=zeilen)
    {
    	if(_query->FieldByName("ein_aus")->AsInteger==0)
    	{
    		_table->Cells[0][ie]=_query->FieldByName("beschreibung")->AsString;
    		_table->Cells[1][ie]=_query->FieldByName("betrag")->AsFloat;
    		ie++;
    	}
    	else
    	{
    		_table->Cells[2][ia]=_query->FieldByName("beschreibung")->AsString;
    		_table->Cells[3][ia]=_query->FieldByName("betrag")->AsFloat;
    		ia++;
    	}
    	_query->Next();
    	i++;
    }
    }
    

    Ist en bissel erweitert worden seit dem Prob mit der Klasse 😉



  • okay, es funzt nun.

    Akari hat eine Zeile gepostet mit folgendem Code:

    myDate.DecodeDate(&day, &month, &day);
    

    richtig ist aber:

    myDate.DecodeDate(&year, &month, &day);
    

    Nachdem ich das geändert hatte war der Fehler weg mit der Zeigeraddition.
    Warum auch immer aber es läuft nun^^

    Danke an alle Helfer


Anmelden zum Antworten