уторак, 29. септембар 2009.

"Безбедне" Ц функције за манипулацију текста

Често се нађем у ситуацији да нисам сигуран да ли одређена ц функција за манипулацију текста (snprintf, strncpy, strncat, ...) исписује тачно "n" карактера, да ли резултирајући стринг завршава нулом итд.

Ради лакшег потсећања, ево примера за сваку од функција:


#include <stdio.h>
#include <string.h>

static void koristi_snprintf(const char *const tekst)
{
    char buf[10];

    snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s", tekst);
    /* Текст који смо добили у buf је можда скраћен, али је коректан са
     * нулом на крају. */
    printf("%s\n", buf);
}


static void koristi_strncpy(const char *const iz)
{
    char u[10];
    const unsigned s = sizeof(u)/sizeof(u[0]);

    strncpy(u, iz, s - 1);
    u[s - 1] = '\0'; /* Морамо ручно да завршимо стринг. */

    printf("%s\n", u);
}


static void koristi_strncat(const char *const tekst)
{
    char buf[10];
    const unsigned s = sizeof(buf)/sizeof(buf[0]);

    strncpy(buf, "12345", s - 1);
    buf[s - 1] = '\0';

    /* Број карактера који функција може да дода је мања за један
     * због завршне нуле и мања за дужину стринга који је већ у
     * баферу. */
    strncat(buf, tekst, s - 1 - strlen(buf));
    printf("%s\n", buf);
}


static void koristi_strncmp(const char *const tekst)
{
    const char buf[] = "12345";
    const unsigned s = sizeof(buf)/sizeof(buf[0]);

    if (strncmp(buf, tekst, s) == 0)
 printf("Prvih %d karaktera su isti\n", s);
    else
 printf("Razlika postoji u prvih %d karaktera\n", s);
}



int main()
{
    koristi_snprintf("Zdravo. Ovaj tekst je predugacak.");
    koristi_strncpy("Zdravo. Ovaj tekst je predugacak.");
    koristi_strncat("Zdravo. Ovaj tekst je predugacak.");
    koristi_strncmp("12345678");
    return 0;
}