首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言字串分割與字串轉浮點數完整實戰指南

     編輯:C 語言問答

場景:CSV 風格數值字串解析

// 輸入範例
"-0.92,-0.60,341.77,-0.15,0.14,0.11,0.02,-0.01,1.00,1.00,447.19,140.02,159.50"

目標:按 , 分割 → 轉為 float/double → 存入陣列。

方法一:標準庫 strtok + strtod(推薦)

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

#define MAX_NUM 100

int parse_csv(const char *input, double *out, int max) {
    char *buf = strdup(input);          // strtok 會修改字串,需複製
    if (!buf) return -1;

    int count = 0;
    char *token = strtok(buf, ",");
    while (token && count < max) {
        char *endptr;
        double val = strtod(token, &endptr);
        if (endptr == token) {          // 無有效數字
            free(buf);
            return -1;
        }
        out[count++] = val;
        token = strtok(NULL, ",");
    }
    free(buf);
    return count;
}

int main() {
    const char *data = "-0.92,-0.60,341.77,-0.15,0.14,0.11,0.02,-0.01,1.00,1.00,447.19,140.02,159.50";
    double nums[MAX_NUM];
    int n = parse_csv(data, nums, MAX_NUM);
    if (n > 0) {
        for (int i = 0; i < n; i++) printf("[%d] %.5f\n", i, nums[i]);
    }
    return 0;
}

方法二:手寫解析器(無庫依賴、教學用)

int manual_parse(const char *s, double *out, int max) {
    int count = 0;
    while (*s && count < max) {
        // 跳過空白
        while (*s == ' ') s++;

        int sign = 1;
        if (*s == '-') { sign = -1; s++; }
        else if (*s == '+') { s++; }

        double val = 0.0;
        int has_digit = 0;
        // 整數部份
        while (*s >= '0' && *s <= '9') {
            val = val * 10 + (*s - '0');
            s++; has_digit = 1;
        }
        // 小數部份
        if (*s == '.') {
            s++;
            double frac = 0.1;
            while (*s >= '0' && *s <= '9') {
                val += (*s - '0') * frac;
                frac *= 0.1;
                s++; has_digit = 1;
            }
        }
        if (!has_digit) break;          // 非數字字元

        out[count++] = sign * val;

        // 跳過分隔符
        while (*s == ' ') s++;
        if (*s == ',') s++;
        else break;
    }
    return count;
}

關鍵函數對比

函數優點缺點
strtok標準、簡潔非執行緒安全、修改原字串、不支援空欄位
strtok_r / strtok_s執行緒安全C11/C17 才標準化,Windows 用 strtok_s
strtod健壯處理科學計數法、十六進制、錯誤報告略重
sscanf格式化強大效能差、緩衝區風險、難處理變長欄位
手寫解析零依賴、完全可控、教學價值高易出邊界錯誤、需自行處理 inf/nan

工程化建議

  1. **生產代碼優先用 strtod**,配合 strtok_r 或自寫分割迭代器。
  2. **嚴格檢查 endptr** 確保整個 token 被消費,防止 "123abc" 偷偷通過。
  3. **大數據量** 考慮 mmap + 狀態機流式解析,避免全量複製。
  4. **國際化**:strtod 受 LC_NUMERIC 影響(小數點可能為 ,),跨平台建議固定 C locale 或手寫解析。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved