Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

สร้างฟังก์ชัน atoi() เองในภาษา C (Custom atoi)


atoi() คืออะไร?

atoi() (ASCII to Integer) เป็นฟังก์ชันมาตรฐานแปลง **String ตัวเลข → Integer** อยู่ใน <stdlib.h>

ข้อจำกัดของ atoi() มาตรฐาน

  • แปลงได้เฉพาะ String ที่เป็นตัวเลขทั้งหมด
  • เจอตัวอักษรไม่ใช่ตัวเลข → หยุดแปลงทันที คืนค่าที่แปลงได้จนถึงจุดนั้น
  • ไม่มีการแจ้ง Error (คืน 0 ทั้งกรณี Error และกรณี String เป็น "0")

ตัวอย่างพฤติกรรม atoi()

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

int main() {
    char str1[] = "3567";
    char str2[] = "TutorialsPoint";
    
    printf("'%s' -> %d\n", str1, atoi(str1)); // 3567
    printf("'%s' -> %d\n", str2, atoi(str2)); // 0 (ไม่ใช่ตัวเลข)
    return 0;
}

สร้าง Custom atoi() ที่ดียิ่งขึ้น

ควรมี:

  1. ตรวจสอบความถูกต้องของ String (Validation)
  2. รองรับเครื่องหมาย + / -
  3. แจ้ง Error ได้ (คืนค่าพิเศษหรือใช้ Pointer parameter)
  4. ป้องกัน Overflow

ตัวอย่าง Custom atoi()

#include <stdio.h>
#include <ctype.h>  // isdigit
#include <limits.h> // INT_MAX, INT_MIN

// คืนค่า 0 ถ้า success, -1 ถ้า error
// ผลลัพธ์เก็บใน *out
int my_atoi(const char *str, int *out) {
    if (!str || !out) return -1;
    
    int sign = 1;
    long long result = 0; // ใช้ long long ป้องกัน overflow ระหว่างคำนวณ
    
    // ข้าม whitespace
    while (isspace(*str)) str++;
    
    // เช็ค sign
    if (*str == '+' || *str == '-') {
        if (*str == '-') sign = -1;
        str++;
    }
    
    // ต้องมีตัวเลขอย่างน้อย 1 ตัว
    if (!isdigit(*str)) return -1;
    
    // แปลงตัวเลข
    while (isdigit(*str)) {
        int digit = *str - '0';
        result = result * 10 + digit;
        
        // Check overflow
        if (sign == 1 && result > INT_MAX) return -1;
        if (sign == -1 && -result < INT_MIN) return -1;
        
        str++;
    }
    
    // ไม่อนุญาตให้มีตัวอักษรเหลือ (strict)
    while (isspace(*str)) str++;
    if (*str != '\0') return -1;
    
    *out = (int)(result * sign);
    return 0;
}

int main() {
    char *tests[] = {"3567", "-42", "+100", "123abc", "abc", "2147483647", "2147483648", ""};
    int result;
    
    for (int i = 0; i < 8; i++) {
        int ret = my_atoi(tests[i], &result);
        if (ret == 0)
            printf("'%s' -> %d ✓\n", tests[i], result);
        else
            printf("'%s' -> ERROR ✗\n", tests[i]);
    }
    return 0;
}

ผลลัพธ์:


'3567' -> 3567 ✓
'-42' -> -42 ✓
'+100' -> 100 ✓
'123abc' -> ERROR ✗
'abc' -> ERROR ✗
'2147483647' -> 2147483647 ✓
'2147483648' -> ERROR ✗ (Overflow)
'' -> ERROR ✗

ฟังก์ชันมาตรฐานที่ดีกว่า atoi()

  • strtol() - แปลงเป็น long, มี Error checking, รองรับ Base (2, 8, 10, 16)
  • strtoll() - แปลงเป็น long long
  • strtoimax() - แปลงเป็น intmax_t

// ใช้ strtol แทน atoi (แนะนำ)
char *endptr;
long val = strtol(str, &endptr, 10);
if (*endptr != '\0') { /* Error: มีตัวอักษรเหลือ */ }