ユーニックス総合研究所

  • home
  • archives
  • c-mojiretsu-suti-henkan

C言語の文字列を数値変換する【atoi, atof, strtol, strtod, etc】

  • 作成日: 2024-03-14
  • 更新日: 2024-03-14
  • カテゴリ: C言語

C言語の文字列を数値に変換する方法を解説します。
文字列を数値変換するための関数はC言語では多数用意されています。
これらの使い方を見ていきます。

C言語や他の言語を扱うYoutubeも公開しています。
興味がある方は以下のリンクからご覧ください。

Youtubeの当チャンネル

atoi, atol, atoll: 整数変換

#include <stdlib.h>  

int atoi(const char *nptr);  
long atol(const char *nptr);  
long long atoll(const char *nptr);  

文字列を整数に変換するにはatoi()atol()atoll()が使えます。
これらの関数は引数の文字列をパースして数値に変換します。

atoi()intに変換。
atol()longに変換。
atoll()long longに変換します。

これらの関数は数値のオーバーフロー、アンダーフローなどのエラーは検出しません。

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

int main(void) {  
    int n = atoi("123");  
    printf("%d\n", n);  // 123  

    n = atoi("-123");  
    printf("%d\n", n);  // -123  

    // オーバーフロー  
    n = atoi("1111111111111111111111111111111");  
    printf("%d\n", n);  // -1  

    // アンダーフロー  
    n = atoi("-111111111111111111111111111111");  
    printf("%d\n", n);  // 0  
    return 0;  
}  

引数にNULLを渡すとセグフォになりプログラムが落ちることがあります。

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

int main(void) {  
    int n = atoi(NULL);  
    // Segmentation fault  
    return 0;  
}  

atof: 実数変換

#include <stdlib.h>  

double atof(const char *nptr);  

文字列を実数に変換するにはatof()を使います。
この関数は引数の文字列をdouble型に変換します。
atoi()と同様にエラーは検出しません。

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

int main(void) {  
    double n = atof("3.14");  
    printf("%f\n", n);  // 3.140000  

    n = atof("-3.14");  
    printf("%f\n", n);  // -3.140000  

    // オーバーフロー  
    n = atof("1.111111112222222233333333");  
    printf("%f\n", n);  // 1.111111  

    n = atof("-1.111111112222222233333333");  
    printf("%f\n", n);  // -1.111111  

    return 0;  
}  

引数にNULLを渡すとセグフォになりプログラムが落ちることがあります。

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

int main(void) {  
    double n = atof(NULL);  
    // Segmentation fault  
    return 0;  
}  

strtol, strtoll: 整数変換

#include <stdlib.h>  

long int strtol(const char *nptr, char **endptr, int base);  

long long int strtoll(const char *nptr, char **endptr, int base);  

エラー検出ありで文字列を整数に変換するにはstrtol(), strtoll()を使います。

strtol()は文字列をlong int型に変換します。
strtoll()は文字列をlong long int型に変換します。

strtol()strtoll()の使い方は同じです。
strtol()についてのみ解説します。

nptrには変換したい文字列を指定します。
strtol()達は変換処理で変換が終わったnptrのポインタの次のポインタをendptrに格納します。
endptrNULLの場合は何もしません。

baseにはnptrが何進数か指定します。
baseの値は2から36の範囲かまたは0でなければいけません。
baseが10の時は10進数としてnptrをパースし、8の時は8進数としてnptrをパースし、16の時は16進数としてnptrをパースします。

baseが0の時はnptrの先頭が0の場合は8進数としてパースします。
nptrの先頭が0xの場合は16進数としてパースします。
それ以外は10進数としてパースします。

これらの関数は値が範囲外の時にerrnoERANGEをセットします。
これを使うとエラーハンドリングできます。

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

int main(void) {  
    {  
        long int n = strtol("123", NULL, 10);  
        printf("%ld\n", n);  // 123  
    }  

    // endptrの動作  
    {  
        // 先頭の空白はスキップする  
        const char *s = "  123 Hello";  
        char *endptr = NULL;  
        long int n = strtol(s, &endptr, 10);  
        printf("%ld [%s]\n", n, endptr);  
        // 123 [ Hello]  
    }  

    // baseが8の場合の動作  
    {  
        // 8進数として変換  
        long int n = strtol("10", NULL, 8);  
        printf("%ld\n", n);  // 8  
    }  

    // baseが16の場合の動作  
    {  
        // 16進数として変換  
        long int n = strtol("10", NULL, 16);  
        printf("%ld\n", n);  // 16  
    }  

    // baseが0の場合の動作  
    {  
        // 10進数として変換  
        long int n = strtol("10", NULL, 0);  
        printf("%ld\n", n);  // 10  
    }  
    {  
        // 先頭が0なら8進数として変換  
        long int n = strtol("010", NULL, 0);  
        printf("%ld\n", n);  // 8  
    }  
    {  
        // 先頭が0xなら16進数として変換  
        long int n = strtol("0x10", NULL, 0);  
        printf("%ld\n", n);  // 16  
    }  

    // エラー処理  
    {  
        errno = 0;  
        strtol("111111111111111111111111111", NULL, 10);  
        if (errno != 0) {  
            switch (errno) {  
            default: break;  
            case ERANGE: perror("strtol"); break;  
            // strtol: Numerical result out of range  
            }  
        }  
    }  
    return 0;  
}  

strtod, strtof, strtold: 実数変換

#include <stdlib.h>  

double strtod(const char *nptr, char **endptr);  
float strtof(const char *nptr, char **endptr);  
long double strtold(const char *nptr, char **endptr);  

エラー検出ありで文字列を実数に変換するにはstrtod()strtof()strtold()を使います。

これらの関数はどれも使い方は一緒です。
ですのでstrtod()のみ解説します。

strtod()達は引数の文字列nptrを実数に変換します。
実数は

  • 3.14
  • +1.23
  • -1.23
  • 1e
  • 1e+2
  • 1e-2

などのフォーマットに対応しています。
文字列の先頭の空白はスキップします。

endptrにはパースした最後のポインタの次のポインタが格納されます。
endptrがNULLの場合は何もしません。

これらの関数はオーバーフローやアンダーフローのエラーが発生した場合はerrnoERANGEをセットします。

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

int main(void) {  
    {  
        double n = strtod("3.14", NULL);  
        printf("%f\n", n);  // 3.140000  
    }  

    // endptrの動作  
    {  
        // 先頭の空白はスキップ  
        const char *s = "  3.14 Hello";  
        char *endptr = NULL;  
        double n = strtod(s, &endptr);  
        printf("%f [%s]\n", n, endptr);  
        // 3.140000 [ Hello]  
    }  

    {  
        double n = strtod("+3.14", NULL);  
        printf("%f\n", n);  // 3.140000  
    }  
    {  
        double n = strtod("-3.14", NULL);  
        printf("%f\n", n);  // -3.140000  
    }  
    {  
        double n = strtod("1e", NULL);  
        printf("%f\n", n);  // 1.000000  
    }  
    {  
        double n = strtod("1e+2", NULL);  
        printf("%f\n", n);  // 100.000000  
    }  
    {  
        double n = strtod("1e-2", NULL);  
        printf("%f\n", n);  // 0.010000  
    }  

    return 0;  
}