Konkatinierung von char* - gängige Praxis



  • pointerbub schrieb:

    Wutz schrieb:

    - nur Deppen benutzen strncpy

    Begründung? Deppen nutzen strcpy.

    Stop using strncpy already!

    pointerbub schrieb:

    Wutz schrieb:

    - es ist nicht sichergestellt, dass argv[0] den Programmnamen enthält

    Wann ist das nicht der Fall?

    Immer dann, wenns dem Host Environment anders einfällt. Garantiert? Nie. Geh Standard lesen.


  • Mod

    Swordfish schrieb:

    pointerbub schrieb:

    Wutz schrieb:

    - es ist nicht sichergestellt, dass argv[0] den Programmnamen enthält

    Wann ist das nicht der Fall?

    Immer dann, wenns dem Host Environment anders einfällt. Garantiert? Nie. Geh Standard lesen.

    Wobei es schon ziemlich spitzfindig ist zu sagen, dass da nicht zuverlässig der Programmaufruf stünde. Ob man für Windows, Linux, Mac oder sonst ein Betriebssystem mit > 0.1 Promille Marktanteil programmiert weiß man schließlich in der Regel. Und dann ist dieses Verhalten auch garantiert. Der eigentliche Knackpunkt ist, dass ich oben nicht ohne Grund "Programmaufruf" geschrieben habe. Der Threadersteller geht aber davon aus, dass da garantiert der Name der Executable mit vollem Pfad stünde. Dies ist definitiv nicht garantiert. Einfache Gegenbeispiele sind Verknüpfungen oder Aliase. Denn in argv[0] steht wirklich der Bezeichner über den das Programm gestartet wurde, dieser ist aber nicht unbedingt der Dateiname¹ der Executable.

    ¹: Es ist auch nicht unbedingt gegeben, dass eine Executable überhaupt einen eindeutigen Dateinamen haben muss (Hardlinks...) oder ob es überhaupt eine Executable-Datei gibt (Builtins...).



  • Swordfish schrieb:

    Stop using strncpy already!

    Das funktioniert aber nur in C++.



  • SG1 schrieb:

    void* ist implizit in jeden anderen Zeiger-Typ konvertierbar. Der Cast ist also unnötig. Wenn Dein Compiler ohne den Cast nicht kompilieren will, ist er kaputt.

    Das wusste ich nicht. Danke für den Hinweis.

    Swordfish schrieb:

    Stop using strncpy already!

    Sehr interessanter Artikel. Dass strcpy anfällig gegenüber Buffer-Overflows ist, war mir klar. Daher habe ich auf das "n" im Namen geachtet. Dass diese Funktionen aber keine Nullterminierung garantieren, war mir nicht klar und mir leuchtet die potenzielle Gefahr ein. Die vorgeschlagene Lösung kommt für mich nicht partiell infrage, weil ich, wie SG1 richtig festgestellt habe, nicht C++ programmiere, sondern ausschließlich C. Vermutlich bleibt mir nicht anderes übrig, als die Funktion selbst zu implementieren.



  • Kann mir jemand sagen, warum im Code von Wutz

    p-*arg+1
    

    16 ergibt? p ist der Pointer auf die Stelle, an der das letzte / steht. *arg ist der erste const char* in a. Wie funktioniert die Zeigerarithmetik hier?



  • *argv zeigt auf den programmpfad, p auf den gefundenen pfadseparator, somit ist p - *argv die distanz der beiden, die anzahl der zeichen bis zum pfadseparator. Damit dieser eingeschlossen wird, noch eins dazuaddiert.



  • pointerbub schrieb:

    Die vorgeschlagene Lösung kommt für mich nicht partiell infrage, weil ich, wie SG1 richtig festgestellt habe, nicht C++ programmiere, sondern ausschließlich C.

    Ich verstehe in diesem Satz das Wort "partiell" nicht. Was sagt es aus?



  • volkard schrieb:

    pointerbub schrieb:

    Die vorgeschlagene Lösung kommt für mich nicht partiell infrage, weil ich, wie SG1 richtig festgestellt habe, nicht C++ programmiere, sondern ausschließlich C.

    Ich verstehe in diesem Satz das Wort "partiell" nicht. Was sagt es aus?

    Das "nicht" ist dieses Mal zu viel ;). Partiell bedeutet teilweise. Der Artikel behauptet nämlich, man solle die entsprechende Codevariante selbst programmieren. Dieser Teil trifft auf mich zu. Jedoch kommt dafür C++ zum Einstz. Dies trifft bei mir nicht zu.

    Techel schrieb:

    *argv zeigt auf den programmpfad, p auf den gefundenen pfadseparator, somit ist p - *argv die distanz der beiden, die anzahl der zeichen bis zum pfadseparator. Damit dieser eingeschlossen wird, noch eins dazuaddiert.

    Danke, das habe ich verstanden. Jedoch ist mir nicht klar, warum die Differenz der Pointer die Anzahl der Zeichen bis zum Pfadseperator angibt. Anscheinend habe ich da noch Defizite im Verständnis der Zeigerarithmetik. Ich subtrahiere ja Adressen von einander. Warum erhalte ich dennnoch das gewünschte Ergebnis?



  • Ah, ich verstehe vermutlich. Diese Art der Rechnung funktioniert nur, weil die Daten hintereinander im Speicher liegt. Ist das richtig?



  • Genau.



  • pointerbub schrieb:

    Das "nicht" ist dieses Mal zu viel ;).

    Deine Postings sind sehr fein zu lesen. Du gibst Dir absolut genug Mühe als Fragesteller.



  • SG1 schrieb:

    Swordfish schrieb:

    Stop using strncpy already!

    Das funktioniert aber nur in C++.

    Eben. Ich bin kein C Programmierer und in C++ brauche ich das normalerweise nicht. Die Probleme von strcpy und strncpy kannte ich aber natürlich schon. Und was ist nun die bevorzugte C Lösung?



  • - strncat mit der Vorbedingung dass ein Leerstring vorliegt (wie im Beispiel oben)
    - sprintf mit precision: sprintf(s,"%.*s",3,"blafasel")

    wobei in beiden Fällen natürlich der Zielspeicher ausreichend groß dimensioniert sein muss, was einem die beiden Varianten NICHT abnehmen.
    Beides geht schon ab C89, garantiert die String-Terminierung und schneidet im Bedarfsfall den Quellstring ab.



  • volkard schrieb:

    pointerbub schrieb:

    Das "nicht" ist dieses Mal zu viel ;).

    Deine Postings sind sehr fein zu lesen. Du gibst Dir absolut genug Mühe als Fragesteller.

    Du hast ja auch die Möglichkeit, deinen einen Satz zweimal nachzukorrigieren. Das ist einem Unregistrierten leider nicht möglich.



  • Dir wird dieses Privileg auch gegönnt sein, für nur 15€ pro Monat für die Mitgliedschaft im C++-Forum.


Anmelden zum Antworten