AnsiString an ein char Array anhängen



  • Hallo,

    @Christian211
    Wenn du ein wenig nachdenkst, wirst du darauf kommen, dass sowohl strcpy als auch strncpy Teil der VCL sind und du deshalb keine zusätzlichen Header einbinden musst.
    Überlegung:
    StrLCopy ist Teil der VCL
    StrLCopy kapselt strcpy
    also muss die string.h (wo strcpy drin ist) in die VCL eingebunden werden
    also ist strcpy Teil der VCL

    [edit]
    Kommando zurück.
    strcpy ist zwar Teil der VCL (das stimmt), StrLCopy kapselt diese Funktion aber nicht. Ich hab mal den Quellcode von StrLCopy angeschaut und der ist reinstes Assembler. Die Wahrheit liegt also mehr in der Mitte.
    [\edit]

    Ciao



  • Christian211 schrieb:

    werte ich als Einsicht, das dein Argument nichtig war. Korrekt?

    - als Entwickler ist man schreibfaul

    Dann bist du auch einer der Entwickler die das Einsparpotential in der Zeit am falschen Ort zu finden glauben.

    Christian211 schrieb:

    - als Anfänger weiss man nicht, dass man eine Header einbinden muss

    Dann lernt man als Anfänger was dazu. Es ist kein Argument, einfach einen Header der alle anderen Header includiert zu propagieren. Das ist absolut am Sinn vorbei und schafft unnötige Abhängigkeiten.

    Christian211 schrieb:

    - als Anfänger weiss man of nicht den Namen der Header zum einbinden (die F1 Taste klemmt ja öfters, und einige Compiler werden offenbar ohne Hilfe ausgeliefert)

    Dann lernt der Anfänger hald, die Taste F1 zu reparieren und entsprechende Dokumentation zu besorgen, denn es wird nicht das letzte mal sein, das die Dokumentation benötigt werden wird.

    Christian211 schrieb:

    Keine Ahnung. Worauf willst du hinaus?

    Was in Gottes Namen hat die Kapselung einer Funktion damit zu tun, ob man sie benutzen sollte oder nicht? Die gnaze VCL kapselt die Win 32 API. Diese Funktionen sind bloß wenig bekannt. Schließlich war hier, bezogen auf die Ausgangsfrage, überhaupt die Nutzung des Typ char unnötig, nur um ab einer bestimmten Stelle etwas mitteles einer Messagebox auszugeben.

    Nur in sehr eingeschränktem Rahmen relevant. Denn so gesehen benötigst du nicht mal StrLCopy, denn AnsiString verfügt ja über die diversen Operatoren die die Verwendung von String-Cat oder String-Copy-Funktionen völlig unnötig machen.

    Christian211 schrieb:

    Weitere Quizfrage: ist strcpy Teil der VCL?

    Wenn du hier Moderator bist, solltest du das eigentlich Wissen. 😉

    ... Offensichtlich hast du nicht gesehen, was ich mit dieser Frage bezwecken wollte. Man msus hier, im VCL Forum nicht alles mit Gewalt auf die VCL umbiegen. Es wurde hier ein nicht glücklich gewähltes Ansi C Element verwendet. Also ist es nur angemessen, wenn ich ein besseres Element aufzeige, das ebenfalls aus der selben Bibliothek stammt wie das unglücklich gewählte. Damit entkräftet man auch gleich einige "aber"-Argumentationen.



  • Interssant jedenfalls, was so ein kleiner Hinweis auf eine VCL Funktion auslösen kann

    Einsparpotential in der Zeit am falschen Ort zu finden glauben

    Danke geht seit 26 Jahren sehr gut 🙂

    @Braunstein
    strncpy war hier auch nur ein Beispiel. Es gibt weitere Standardfunktioen, für die es entsprechende Funktionen in der VCL gibt und für die dann *.h rein muss



  • Christian211 schrieb:

    Einsparpotential in der Zeit am falschen Ort zu finden glauben

    Danke geht seit 26 Jahren sehr gut 🙂

    Stimmt... denn Tipparbeit ist ja auch bei der Softwarentwicklung der absolute Zeitfresser... egal. Ist ein anderes Thema.

    Was mich viel eher interessieren würde, ist die Tatsache, was du eigentlich für ein Problem mit dem Includieren von headerfiles hast:

    Christian211 schrieb:

    Kann ich nicht nachvollziehen. Für strncpy und weitere sind Headerdateien einzubinden für die entsprechende VCL Funktion nicht.

    Es ist doch genau der tiefere Sinn, das man nur headerfiles included die man auch benötigt. Oder gehörst du auch zu denen die ein Headerfile "includeAll.h" machen, wo schlussendlich eine Liste mit #include für jedes erdenkliche Headerfile steht, womöglihc noch einige using-Anweisungen, und dann das einfach in alle Module "includeall.h" includen?



  • KlausB schrieb:

    wo ist denn da das "new" und das "delete"
    desweiteren ist das sehr gefaehrlich den char* auf 30 Zeichen festzulegen
    was passiert denn wenn du mehr als 30 Zeichen da reinschreibst

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	char* Message;
    	if(OpenDialog1->Execute())
         {
    	     Message = new char[OpenDialog1->FileName.Length()+20];
              Message = "File->";
         	strcpy(Message+6,OpenDialog1->FileName.c_str());
         	Application->MessageBox(Message,"File",MB_OK);
    	     delete Message;
         }
    
    }
    

    Gibt aber folgendes Problem, im Caption der MessageBox steht nicht File sondern
    ein Rest von Message. Habe mir Message genauer angeschaut, ist aber alles
    korrekt.



  • Wie wäre es mit

    String Message;
    if(OpenDialog1->Execute())
       {
       Message="File->"+OpenDialog1->FileName;
       Application->MessageBox(Message.c_str(),"File",MB_OK);
       }
    


  • Nein, ich includiere auch nur was nötig ist.

    Was hast du gegen eine kleine harmlose VCL Funktion?

    Richtig für strxxx ist keine Header einzubinden. Irrtum von mir.



  • Simmt, habe mal wieder nach dem Motto warum Einfach wenn es auch Umständlich
    geht gehandelt.

    Danke für die Hilfe...



  • hermes schrieb:

    Message = new char[OpenDialog1->FileName.Length()+20];
              Message = "File->";
         	strcpy(Message+6,OpenDialog1->FileName.c_str());
         	Application->MessageBox(Message,"File",MB_OK);
    	     delete Message;
    

    Nanana, zu einem new [] gehört auch ein delete []...

    @Christian: Gar nichts. Hab nur ein Problem mit der Argumentation "da muss ich extra noch ne Headerfile einbinden". Was glaubst du was VCL.h anderes macht?



  • Dann sollte man diese Diskussion beenden und jede nimmt das, was gerade am besten passt



  • Ups, delete[].

    Message = new char[OpenDialog1->FileName.Length()+20];
             Message = "File->";
             strcpy(Message+6,OpenDialog1->FileName.c_str());
             Application->MessageBox(Message,"File",MB_OK);
             delete[] Message;
    

    Ich weiss allerdings immer noch nicht, warum im Caption von der MessageBox
    nicht File sondern Reste von Message steht.
    Message sieht eigentlich korrekt aus.
    Was passiert eigentlich bei delete ohne [], wird da nur die Speicherstelle
    für den Pointer freigegeben, der angefordert Speicher aber nicht.



  • Welches delete du hier verwendest ist sowieso egal da du bei

    Message = "File->";
    

    den vorher geholten Pointer ja wieder überschreibst.
    also lieber

    strncpy(Message,"File->",OpenDialog1->FileName.Length()+19);
    

    und dann

    strncat(Message,OpenDialog1->FileName.c_str(),,OpenDialog1->FileName.Length()+19);
    

    Ich würde der Übersichtlichkeit halber die maximale Größe deines Arrays vorher in eine Variable schreiben.
    Noch besser ist aber die AnsiString-Variante von Christian.

    Ein einfaches delete würde hier den Speicher des ersten Elementes deines Arrays freigeben.
    also immer:
    bei new []
    immer delete[]



  • Welches delete du hier verwendest ist sowieso egal da du bei
    Message = "File->";
    den vorher geholten Pointer ja wieder überschreibst.

    Gebe zu habe hier noch so meine Problem.

    char* Message;

    Message = new char[20];
    Message = "File";

    Klar, ich überschreibe den Pointer.
    void test(char* x)
    {
    *x = 10; // Hier beschreibe ich indirect über den Zeiger
    // die Speicherstelle
    }
    *Message = 1; //Hier beschreibe ich die erste Speicherstelle des
    //Arrays indirect über den Pointer.

    Message = "File"; //Ist aber nicht möglich das verwirrt ein bischen.
    //Cannot convert char
    to char, wieso *Message ist
    //doch der Zeiger auf ein char Array.

    Sprich ich möchte das Array mit einem String initialisieren wie

    char x[] = "File";
    Hier habe ich allerdings keinen Speicher allociert.



  • *Message ist das erste Element deines char Arrays (* ist der Dreferenzierungsoperator) und somit natürlich ein char während "File" ein Stringliteral und somit ein const char* ist.
    Message ist der Zeiger auf dein char-Array.



  • Message = "File";
    Hier überschreibe ich also den Pointer Message mit dem const char Pointer des Stringliterals.

    Wenn ich soetwas schon mache, sollte ich zumindest Casten.
    Message = (char*)"Hallo";
    oder?



  • Nein. Sowas sollte man überhaupt nicht machen.
    Zuweisungen von Stringliteralen sollten nur bei der Deklaration gemacht werden. Also so etwas

    const char* Message = "File";
    


  • Jo, danke für die Lehrreiche Diskussion.



  • Hallo ich nochmal,

    Message = "File"; //Fehlermeldung des Compilers:
    //Cannot convert char
    to char.

    während "File" ein Stringliteral und somit ein const char* ist.

    Dann verstehe ich allerdings die Fehlermeldung des Compilers nicht.
    Müsste es dann nicht, Cannot convert const char* to char, heissen?



  • Mit *Message dereferenzierst Du das erste Zeichen aud dem char-Array (char*) Message. Somit ist *Message ein einzelnes char aus dem Array - und die Fehlermeldung absolut korrekt.

    *Message = 'F';
    

    wäre in Ordnung...


Anmelden zum Antworten