Atoi/Strtol Yerine Güvenli: String'ten Sayı Dönüşüm Hataları

String'ten sayıya dönüştürme işlemi çoğu yazılımcı tarafından hafife alınır. Oysa atoi() ve strtol() gibi klasik fonksiyonlar hata yönetimi yapmaz ve güvenlik açıkları doğurabilir. Overflow, underflow, invalid input gibi durumlar sessizce geçer ve beklenmedik davranışlar yaratır.

Asıl sorun şu: atoi() hata döndürmez. Geçersiz giriş varsa 0 döner, ama sıfır da geçerli bir sayı olabilir. Bu ayrımı yapamayız. strtol() biraz daha iyidir ama yine de dikkat gerekir.

C'de güvenli yöntem:

1#include <stdlib.h>
2#include <errno.h>
3#include <limits.h>
4#include <stdio.h>
5
6int safe_strtol(const char *str, long *result) {
7char *endptr;
8errno = 0;
9long val = strtol(str, &endptr, 10);
10
11// Overflow/underflow kontrol
12if (errno == ERANGE) {
13printf("Hata: Sayı sınırları aştı\n");
14return 0;
15}
16
17// Hiç dönüştürülen karakter yok
18if (endptr == str) {
19printf("Hata: Geçerli sayı bulunamadı\n");
20return 0;
21}
22
23// Dönüştürülen sonra kalan karakter var
24if (*endptr!= '\0') {
25printf("Hata: Fazladan karakter var: %s\n", endptr);
26return 0;
27}
28
29*result = val;
30return 1;
31}
32
33int main() {
34long num;
35
36if (safe_strtol("12345", &num)) {
37printf("Başarılı: %ld\n", num);
38}
39
40if (safe_strtol("abc", &num)) {
41printf("Başarılı: %ld\n", num);
42} else {
43printf("Dönüştürme başarısız\n");
44}
45
46if (safe_strtol("999999999999999999999", &num)) {
47printf("Başarılı: %ld\n", num);
48} else {
49printf("Dönüştürme başarısız\n");
50}
51
52return 0;
53}

Beklenen çıktı:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1Başarılı: 12345
2Hata: Geçerli sayı bulunamadı
3Dönüştürme başarısız
4Hata: Sayı sınırları aştı
5Dönüştürme başarısız

C++'da daha modern:

1#include <iostream>
2#include <stdexcept>
3#include <string>
4
5long safe_convert(const std::string &str) {
6try {
7size_t idx;
8long val = std::stol(str, &idx);
9
10if (idx!= str.length()) {
11throw std::invalid_argument("Fazladan karakter");
12}
13return val;
14} catch (const std::invalid_argument &e) {
15std::cerr << "Hata: Geçersiz sayı\n";
16throw;
17} catch (const std::out_of_range &e) {
18std::cerr << "Hata: Sayı sınırları aştı\n";
19throw;
20}
21}
22
23int main() {
24try {
25std::cout << safe_convert("12345") << std::endl;
26std::cout << safe_convert("abc") << std::endl;
27} catch (...) {
28return 1;
29}
30return 0;
31}

Sık yapılan hatalar:

1. errno kontrol etmemek: Overflow sessizce geçer, INT_MAX döner.
2. endptr görmezden gelmek: "123abc" string'i 123'e dönüştürür, kalanı yok sayar.
3. atoi() kullanmak: Hiç hata döndürmez; sadece eski kodlarda kalmış.
4. Input sanitize etmemek: Boşluk, negatif işaret gibi durumları test etmeyin.

Güvenli dönüştürme, hata yönetimi ile başlar. Hiçbir giriş güvenilir değildir.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz