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() ที่ดียิ่งขึ้น
ควรมี:
- ตรวจสอบความถูกต้องของ String (Validation)
- รองรับเครื่องหมาย + / -
- แจ้ง Error ได้ (คืนค่าพิเศษหรือใช้ Pointer parameter)
- ป้องกัน 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: มีตัวอักษรเหลือ */ }