C-keel: Kuidas teisendada stringe ja arve turvaliselt (näidete ja koodiga)

1. Sissejuhatus: Stringide ja arvude teisendamise olulisus C-keeles

C-keeles programmeerimisel on stringide ja arvude vahelised teisendused väga olulised toimingud. Eriti sageli on vaja teisendada string arvuks näiteks kasutajalt sisendi või välistest failidest andmete töötlemisel. Samuti tuleb sageli teisendada arv stringiks, näiteks arvutustulemuste või logide jaoks.

Selliste teisenduste tegemiseks on mitu meetodit ning õige valik sõltub kasutusolukorrast. Selles artiklis selgitatakse põhjalikult, kuidas teisendada stringe ja arve C-keeles ning käsitletakse ka vigade käsitlemist ja turvalisi kasutusviise.

2. Kuidas teisendada stringi arvuks C-keeles

Põhiline string → täisarv teisendus atoi() funktsiooniga

C-keeles stringi täisarvuks teisendamiseks kasutatakse kõige lihtsamalt atoi() funktsiooni. Selle funktsiooni kasutamine on lihtne, kuid sellel on ka puudusi. Allpool on toodud põhiline kasutusnäide.

#include <stdio.h>
#include <stdlib.h>

int main() {
    char str[] = "123";
    int num = atoi(str);
    printf("Pärast teisendamist: %d\n", num);
    return 0;
}

atoi() on lihtne, kuid sellel puudub korralik veakontroll. Näiteks, kui sisend ei ole korrektne, ei teavita see funktsioon vigadest. Järgmises näites näidatakse atoi() käitumist kehtetu stringi korral.

char str[] = "123abc";
int num = atoi(str);  // Teisendab ainult "123", ülejäänut ignoreeritakse

atoi() tagastab teisendatud osa ka siis, kui stringis on kehtetud märgid, mistõttu turvalisemates süsteemides tuleks seda vältida.

Turvaline teisendus strtol() funktsiooniga

Kui on vaja veakontrolli, on soovitatav kasutada strtol() funktsiooni. strtol() võimaldab tegeleda kehtetute sisenditega, töötab erinevate arvusüsteemidega ning võimaldab ka veahaldust. Allpool on näide strtol() kasutamisest stringi turvaliseks teisendamiseks täisarvuks.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    char str[] = "123abc";
    char *endptr;
    errno = 0;  // Lähtesta veaseisund
    long num = strtol(str, &endptr, 10);

    if (errno != 0 || *endptr != ' ') {
        printf("Teisendus ebaõnnestus.\n");
    } else {
        printf("Pärast teisendamist: %ld\n", num);
    }

    return 0;
}

Selles koodis kasutatakse endptr muutujaid kehtetu osa tuvastamiseks ning errno kontrollimiseks, et tuvastada näiteks ületäitumist või alatäitumist.

年収訴求

3. Kuidas teisendada arvu stringiks C-keeles

sprintf() funktsioon ja selle riskid

Arvu stringiks teisendamiseks kasutatakse sprintf() funktsiooni. sprintf() teisendab arvu määratud vormingu järgi stringiks ja kirjutab selle puhvri. Kuid tuleb olla ettevaatlik puhvri ületäitumise riski suhtes. Allpool on põhiline näide kasutamisest.

#include <stdio.h>

int main() {
    int num = 123;
    char str[10];
    sprintf(str, "%d", num);
    printf("Pärast teisendamist: %s\n", str);
    return 0;
}

Selles koodis teisendatakse täisarv stringiks, kuid kui teisendatud string ületab puhvri suuruse, võib tekkida ületäitumine.

Turvaline teisendus snprintf() abil

Puhvri ületäitumise vältimiseks on soovitatav kasutada snprintf() funktsiooni. snprintf() võimaldab määrata puhvri suuruse, ülejäänud osa lõigatakse ära. Vaata järgmist näidet.

#include <stdio.h>

int main() {
    int num = 12345;
    char str[5];
    snprintf(str, sizeof(str), "%d", num);
    printf("Pärast teisendamist: %s\n", str);  // Kuna puhver on väike, on tulemus "1234"
    return 0;
}

Selles näites lõigatakse väljund ära, kui see ületab puhvri suuruse. snprintf() kasutamine aitab vältida ületäitumist ja on turvalisem.

4. Praktiline näide: Stringide ja arvude kahepoolne teisendamine

C-keeles on sageli vaja teisendada stringe ja arve mõlemas suunas. Allpool olevas koodis kasutatakse sscanf() ja snprintf() funktsioone nii stringist arvuks kui ka arvust stringiks teisendamiseks.

#include <stdio.h>

int main() {
    char str[] = "12345";
    int num;
    sscanf(str, "%d", &num);
    printf("Stringist arvuks: %d\n", num);

    char new_str[10];
    snprintf(new_str, sizeof(new_str), "%d", num);
    printf("Arvust stringiks: %s\n", new_str);

    return 0;
}

Selles näites teisendatakse esmalt sscanf() abil string arvuks ja seejärel snprintf() abil arv uuesti stringiks. Selline kahepoolne teisendus on väga kasulik näiteks sisendandmete töötlemisel ja tulemuste väljastamisel.

5. Veakäsitlus ja ettevaatusabinõud

Ületäitumise ja alatäitumise käsitlemine

Arvu stringiks teisendamisel võib tekkida ületäitumine või alatäitumine. Eriti siis, kui teisendatud arv ületab tüübi piirid, võib tekkida viga. strtol() või sscanf() kasutamisel on oluline kontrollida vigu järgmiselt:

if (errno == ERANGE) {
    printf("Tekkis ületäitumine või alatäitumine.\n");
}

errno kontrollimisega saab tuvastada, kas tekkis viga. Vigade korrektne käsitlemine aitab vältida ootamatut käitumist programmis.

Kehtetu sisendi käsitlemine

Kui string on vales vormingus, võib teisendamine arvuks ebaõnnestuda. Näiteks kui üritada teisendada stringi "123abc", teisendatakse ainult numbriline osa ja ülejäänu jäetakse tähelepanuta. Selle vältimiseks kasutatakse strtol() funktsioonis teisenduse positsiooni määramiseks osutajat.

char *endptr;
long num = strtol(str, &endptr, 10);
if (*endptr != ' ') {
    printf("Sisendis on kehtetuid andmeid.\n");
}

6. Kokkuvõte

Veakontrolli mitte unustamine ning turvaliste meetodite kasutamine stringide ja arvude teisendamisel on programmi stabiilsuse tagamiseks väga oluline. atoi() on lihtne kasutada, kuid ei võimalda veahaldust, seega on parem kasutada turvalisemaid funktsioone nagu strtol(), sscanf() ja snprintf().

Stringide ja arvude teisendamine C-keeles on programmeerija jaoks põhiline oskus. Selle oskuse omandamine aitab kirjutada töökindlamaid programme. Lisaks on oluline tegeleda veakäsitluse ja mäluhaldusega, et tagada programmi turvalisus.

Lisalugemine

Kui soovid sellel teemal rohkem teada saada, tutvu ametlike dokumentatsioonidega või vaata avatud lähtekoodiga projektide koodi. Samuti on saadaval palju raamatuid C-keele veakäsitlusest ja mäluhaldusest, mida soovitame samuti uurida.

年収訴求