String terminierung



  • Hallo,
    kann ich auch einen String so terminieren:

    sprintf(temp,"%s\0",buf);
    

    Oder besser so:

    temp[strlen(temp)+1] = '\0';
    

    Erzielen die beiden Zeilen auch die gleichen Ergebnisse?



  • alle string Literale (also text in anführungezeichen" sind immer \0-terminiert. Du brauchst deshalb sie selbst nicht zu terminieren "abc" und "abc\0" sind inhaltlich gleich.

    sprintf(temp,"%s",buf);
    

    ist bereits \0-terminiert.

    strlen erwartet aber \0-terminierte Strings, wenn temp nicht \0-terminiert ist, dann bringt strlen(temp) ein underfiniertes Verhalten hervor und endet meistens mit segfault, also ist dein zweiter Ansatz einfach falsch.



  • Die Frage ist, warum willst du den String, wenn er schon terminiert ist, nochmal händisch terminieren?

    sprintf(temp,"%s\0",buf);
    

    Der Formatstring endet für den Parser bei \0 und sprintf terminiert sowieso immmer den String selbständig, du erreichst nichts.

    temp[strlen(temp)+1] = '\0';
    

    Wennschon dann

    temp[strlen(temp)] = '\0';
    

    aber auch hier setzt du beim Aufruf von strlen ja schon die Terminierung voraus, welche du anschließend nochmal überschreibst.

    temp[strlen(temp)+1] = '\0';
    

    Erreicht nur eine doppelte Terminierung, was manchmal gebraucht wird aber sicher nicht für deine Zwecke.



  • Ich habe gerade mit meinem Kollegen eine Diskussion über das Terminieren von Strings bei snprintf.

    Folgendes Beispiel:

    #include <stdio.h>
    #include <string.h>
    
    int main ( int args, char **argv )
    {
            char buffer[10];
    
            //memset(buffer, 10, 0xff);
            snprintf(buffer, sizeof(buffer),"%s",  argv[1]);
            printf("%s\n", buffer);
            return 0;
    }
    

    Wenn ich das Programm nun mit einem string als Parameter aufrufe, dann wird argv[1] in den buffer kopiert.

    Wenn der Parameter 1 aber länger als der Buffer ist, dann wird nur ein Teilstring in den Buffer kopiert.

    MUSS nach dem snprintf der buffer noch terminiert werden oder nicht?
    Ich sage NEIN und mein Kollege sagt ja.

    Wenn ich mir das ganze aber mit dem gdb ansehe, dann werden aus dem Parameter immer nur maximal 9 Zeichen kopiert und am ende steht immer eine \0

    Ist meine Annahme richtig und man muss es nicht terminieren?
    Ist es abhängig von der libc Version oder sonst was?

    Es ist mehr eine Grundsatzfrage aber trotzdem.
    Wir sind mit gcc auf Linux unterwegs.

    Gruß
    DS



  • MUSS nach dem snprintf der buffer noch terminiert werden oder nicht?

    Schreibe doch einfach einen kleinen Test, der genau dein Szenario umsetzt. Dann schaust du dir das letzte Zeichen an. Ist es 0, dann hast du gewonnen, wenn nicht dein Kollege.



  • Bei so etwas schaut man am besten mal nach, was der Standard dazu sagt.

    Schau mal in den ersten Beitrag in diesem Unterforum Linkliste für Neulinge

    C99-Standard schrieb:

    #include <stdio.h>
    int snprintf(char * restrict s, size_t n, const char * restrict format, ...);
    

    ... If n is zero, nothing is written, and s may be a null pointer. Otherwise, output characters beyond the n-1st are discarded rather than being written to the array, and a null character is written at the end of the characters actually written into the array. ...



  • knivil schrieb:

    MUSS nach dem snprintf der buffer noch terminiert werden oder nicht?

    Schreibe doch einfach einen kleinen Test, der genau dein Szenario umsetzt. Dann schaust du dir das letzte Zeichen an. Ist es 0, dann hast du gewonnen, wenn nicht dein Kollege.

    Beispiel steht doch oben und das ich mit gdb geschaut habe habe ich auch geschrieben.
    In der man page steht es nicht eindeutig drinnen.

    Ich glaube ich habe gewonnen 😃

    Nun hat er mir aber ein Beispiel mit strncpy gezeigt wo es nicht terminiert wird.
    Naja gut in dem Fall hat er halt recht.



  • decembersoul schrieb:

    In der man page steht es nicht eindeutig drinnen.

    dann ist deine manpage kagge.
    das verhalten bezüglich deiner genannten funktionen kann man in jeder halbwegs vernünftigen referenz nachlesen.



  • decembersoul schrieb:

    Nun hat er mir aber ein Beispiel mit strncpy gezeigt wo es nicht terminiert wird.
    Naja gut in dem Fall hat er halt recht.

    Das ist ja auch eine andere Funktion und dort ist es auch entsprechend dokumentiert.

    strncat() jedenfalls hängt die '\0' wieder richtig dran.


Log in to reply