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>56int safe_strtol(const char *str, long *result) {7char *endptr;8errno = 0;9long val = strtol(str, &endptr, 10);1011// Overflow/underflow kontrol12if (errno == ERANGE) {13printf("Hata: Sayı sınırları aştı\n");14return 0;15}1617// Hiç dönüştürülen karakter yok18if (endptr == str) {19printf("Hata: Geçerli sayı bulunamadı\n");20return 0;21}2223// Dönüştürülen sonra kalan karakter var24if (*endptr!= '\0') {25printf("Hata: Fazladan karakter var: %s\n", endptr);26return 0;27}2829*result = val;30return 1;31}3233int main() {34long num;3536if (safe_strtol("12345", &num)) {37printf("Başarılı: %ld\n", num);38}3940if (safe_strtol("abc", &num)) {41printf("Başarılı: %ld\n", num);42} else {43printf("Dönüştürme başarısız\n");44}4546if (safe_strtol("999999999999999999999", &num)) {47printf("Başarılı: %ld\n", num);48} else {49printf("Dönüştürme başarısız\n");50}5152return 0;53}Beklenen çıktı:
1Başarılı: 123452Hata: Geçerli sayı bulunamadı3Dönüştürme başarısız4Hata: Sayı sınırları aştı5Dönüştürme başarısızC++'da daha modern:
1#include <iostream>2#include <stdexcept>3#include <string>45long safe_convert(const std::string &str) {6try {7size_t idx;8long val = std::stol(str, &idx);910if (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}2223int 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.
0 yorum