การแปลง String เป็น Double ใน C/C++ ทำได้หลายวิธี โดยหลักๆ ใช้ strtod() (C) หรือ std::stod (C++)
วิธีที่ 1: strtod() - C Standard (แนะนำ)
#include <stdio.h>
#include <stdlib.h>
int main() {
char s[] = "18.2894 is a number";
char *endptr;
double result;
result = strtod(s, &endptr);
printf("Converted number: %f\n", result); // 18.289400
printf("Remaining string: %s\n", endptr); // " is a number"
printf("Parsed chars: %td\n", endptr - s); // 7
return 0;
}
ผลลัพธ์
Converted number: 18.289400
Remaining string: is a number
Parsed chars: 7
strtod() ไวยากรณ์และพฤติกรรม
double strtod(const char *nptr, char **endptr);
- ข้าม Whitespace นำหน้า
- Parse ตัวเลข: [
] [. ] [ [ ] ] - หยุดที่ตัวอักษรที่ไม่ใช่ตัวเลขตัวแรก
endptrชี้ไปที่ตัวอักษรแรกที่ไม่ได้ Parse (หรือ NULL ถ้าไม่ต้องการ)- คืนค่า 0.0 ถ้าไม่ Parse ได้เลย
- Set
errno = ERANGEถ้า Overflow/Underflow
วิธีที่ 2: sscanf() - Simple Parsing
#include <stdio.h>
int main() {
char s[] = "18.2894";
double result;
if (sscanf(s, "%lf", &result) == 1) {
printf("Converted: %f\n", result);
} else {
printf("Parse failed\n");
}
return 0;
}
ข้อจำกัด: ไม่บอกว่าอ่านได้กี่ตัวอักษร, ไม่ Handle Trailing Chars ได้ดี
วิธีที่ 3: C++ std::stod (C++11+)
#include <iostream>
#include <string>
int main() {
std::string s = "18.2894 is a number";
size_t pos = 0;
try {
double result = std::stod(s, &pos);
std::cout << "Converted: " << result << "\n";
std::cout << "Parsed chars: " << pos << "\n";
std::cout << "Remaining: " << s.substr(pos) << "\n";
} catch (const std::invalid_argument& e) {
std::cerr << "Invalid format\n";
} catch (const std::out_of_range& e) {
std::cerr << "Out of range\n";
}
return 0;
}
ผลลัพธ์
Converted: 18.2894
Parsed chars: 7
Remaining: is a number
วิธีที่ 4: C++ Stringstream (Legacy)
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::string s = "18.2894";
std::stringstream ss(s);
double result;
if (ss >> result) {
std::cout << "Converted: " << result << "\n";
}
return 0;
}
ฟังก์ชันแปลงชนิดอื่น (C)
| ฟังก์ชัน | Header | แปลงเป็น | Base |
|---|---|---|---|
strtol() | stdlib.h | long int | 10 (default) / 2-36 |
strtoul() | stdlib.h | unsigned long | 10 / 2-36 |
strtoll() | stdlib.h | long long (C99) | 10 / 2-36 |
strtoull() | stdlib.h | unsigned long long (C99) | 10 / 2-36 |
strtof() | stdlib.h | float (C99) | - |
strtod() | stdlib.h | double | - |
strtold() | stdlib.h | long double (C99) | - |
Error Handling Pattern (แนะนำ)
double safeStrtod(const char *str, bool *success) {
char *endptr;
errno = 0; // Reset errno
double val = strtod(str, &endptr);
// Check errors
if (endptr == str) { // No digits parsed
*success = false;
return 0.0;
}
if (errno == ERANGE) { // Overflow/Underflow
*success = false;
return val; // HUGE_VAL or 0.0
}
if (*endptr != '\0') { // Trailing garbage (optional check)
// Partial parse - decide if acceptable
}
*success = true;
return val;
}
สรุป
- C: ใช้
strtod()- Robust, ให้ End Pointer, Error Handling ดี - C++: ใช้
std::stod()- Exception Safety, String Integration - หลีกเลี่ยง:
atof()(No Error Detection),sscanf()(Limited Info) - ตรวจสอบ
endptrและerrnoเสมอ