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

วิธีแปลง String เป็น Double ใน C/C++

การแปลง 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.hlong int10 (default) / 2-36
strtoul()stdlib.hunsigned long10 / 2-36
strtoll()stdlib.hlong long (C99)10 / 2-36
strtoull()stdlib.hunsigned long long (C99)10 / 2-36
strtof()stdlib.hfloat (C99)-
strtod()stdlib.hdouble-
strtold()stdlib.hlong 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 เสมอ