strtod是C語言中的標準函數,主要用來把字符串轉換成double類型的浮點數。它的原型如下:
double strtod(const char *nptr, char **endptr);
其中nptr為待轉換的字符串指針,endptr指向待轉換的字符串中第一個非數字或點的字符的指針。如果沒有執行任何轉換,endptr指向待轉換字符串的起始地址。
一、字符串轉換
strtod函數的主要用途是將字符串轉換成double類型的浮點數,這是它最常用的功能。在轉換時,strtod會自動跳過前導空格,並處理負數、科學計數法等特殊情況。
以下是一個簡單的例子:
const char *str = "3.1415926";
char *end;
double num = strtod(str, &end);
在這個例子中,strtod函數執行後num的值為3.1415926,end指針指向字符串結尾的’\0’。需要注意的是,如果待轉換的字符串中包含非數字或點之外的字符,strtod函數只會轉換到第一個非數字或點之前的部分,後面的內容會被忽略掉。
下面是一個包含特殊情況的例子:
const char *str = "-1.23E-4";
char *end;
double num = strtod(str, &end);
在這個例子中,待轉換的字符串包含負號、小數點和科學計數法三個特殊情況。在轉換時,strtod會將它們轉換成對應的浮點數。執行後num的值為-0.000123,end指針指向字符串結尾的’\0’。
二、錯誤處理
在實際應用中,待轉換的字符串可能會包含一些不能正確轉換成浮點數的字符,或者指針參數傳入不正確等情況。為了在這些情況下保證程序的穩定性,strtod函數提供了一些錯誤處理機制。
1.轉換失敗
如果待轉換的字符串中不包含任何數字或點,或者出現了既非數字又不是點的字符,strtod函數會返回0.0並賦值全局變量errno為ERANGE。例如:
const char *str = "abc";
char *end;
double num = strtod(str, &end);
if (*end == '\0' && errno == ERANGE) {
printf("轉換失敗\n");
}
在這個例子中,因為字符串中既沒有數字也沒有點,所以轉換失敗,num的值為0.0,end指針指向字符串結尾的’\0’,errno被賦值為ERANGE。
2.指針參數不正確
如果指針參數end傳入了不正確的值,strtod函數也會返回0.0並賦值全局變量errno為EINVAL。例如:
const char *str = "3.14";
double num = strtod(str, NULL);
if (errno == EINVAL) {
printf("指針參數不正確\n");
}
在這個例子中,因為指針參數end傳入了NULL,所以調用函數時會返回0.0,並將errno賦值為EINVAL。
3.溢出
如果待轉換的字符串表示的浮點數超出了double類型的範圍,strtod函數會返回正負無窮大,並賦值全局變量errno為ERANGE。例如:
const char *str = "1e308";
char *end;
double num = strtod(str, &end);
if (*end == '\0' && errno == ERANGE) {
printf("超出範圍\n");
}
在這個例子中,因為待轉換的字符串表示的浮點數超過了double類型所能表示的最大值,所以函數調用會返回正無窮大,end指針指向字符串結尾的’\0’,errno被賦值為ERANGE。
三、函數實現
strtod函數的實現可分為以下幾步:
1.跳過前導空格和符號判斷
strtod函數會先跳過待轉換字符串中的空格和製表符等空白字符,然後判斷第一個非空白字符是不是符號(+或-)。如果是,會將該符號的正負性作為標記(sign)存儲下來,然後將指針向後移動一位。
2.處理小數部分
接下來,strtod函數會處理小數部分(如果有的話)。它會遍歷字符串,直到遇到非數字或點的字符。在遍歷的過程中,strtod會將遇到的數字按權相加的方式計算出浮點數的整數部分(integer part)和小數部分(fraction part)。例如,在處理字符串”3.14″時,strtod會先計算出整數部分3,然後根據小數點後面的數字1和4計算出小數部分0.14(1/10 + 4/100)。
3.處理指數部分
如果待轉換字符串中包含科學計數法(例如3.14E5),strtod函數會處理指數部分。它會提取出E或e後面的數字作為指數(exponent),然後將整個浮點數乘以10的exponent次方。例如,在處理字符串”3.14E5″時,strtod會先計算出浮點數3.14,然後將其乘以10的5次方。
4.返回結果
最後,strtod函數會根據前面計算出來的數值、符號和指數等信息,計算出最終的浮點數,並把它返回。
下面是一個簡化版的strtod函數實現:
double my_strtod(const char *nptr, char **endptr) {
// 跳過前導空格和符號
char *p = (char *)nptr;
while (isspace(*p)) p++;
int sign = 1;
if (*p == '+') {
p++;
} else if (*p == '-') {
p++;
sign = -1;
}
// 處理小數部分
double integer_part = 0.0;
double fraction_part = 0.0;
double divisor = 1.0;
while (isdigit(*p) || *p == '.') {
if (*p == '.') {
divisor = 10.0;
p++;
continue;
}
if (divisor == 1.0) {
integer_part = integer_part * 10.0 + (*p - '0');
} else {
fraction_part += (*p - '0') / divisor;
divisor *= 10.0;
}
p++;
}
// 處理指數部分
int exponent = 0;
if (toupper(*p) == 'E') {
p++;
int exp_sign = 1;
if (*p == '+') {
p++;
} else if (*p == '-') {
p++;
exp_sign = -1;
}
while (isdigit(*p)) {
exponent = exponent * 10 + (*p - '0');
p++;
}
exponent *= exp_sign;
}
// 返回結果
if (endptr != NULL) {
*endptr = p;
}
return sign * (integer_part + fraction_part) * pow(10, exponent);
}
四、總結
strtod函數是C語言中常用的一個函數,主要用來將字符串轉換成double類型的浮點數。在實際應用中,strtod函數還會根據待轉換字符串的不同情況返回不同的錯誤碼,方便程序員進行錯誤處理。
本文主要闡述了strtod函數的用法和實現方法,並給出了一個簡化版的實現代碼,供讀者參考。
原創文章,作者:FMFB,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/149431.html