41.3 문자열을 실수로 변환하기

이번에는 문자열을 실수로 바꿔보겠습니다. atof 함수를 사용하면 문자열을 실수로 바꿀 수 있으며 함수 이름은 ASCII string to float에서 따왔습니다(stdlib.h 헤더 파일에 선언되어 있습니다).

  • atof(문자열);
    • double atof(char const *_String);
    • 성공하면 변환된 실수를 반환, 실패하면 0을 반환

ascii_string_to_float.c

#include <stdio.h>
#include <stdlib.h>    // atof 함수가 선언된 헤더 파일

int main()
{
    char *s1 = "35.283672";  // "35.283672"은 문자열
    float num1;

    num1 = atof(s1);         // 문자열을 실수로 변환하여 num1에 할당

    printf("%f\n", num1);    // 35.283672

    return 0;
}

실행 결과

35.283672

atof 함수에 문자열을 넣어주면 실수가 반환됩니다. 단, 문자열은 실수로 되어있어야 하며 알파벳 영문자, 특수 문자가 포함되면 해당 문자부터는 변환을 하지 않습니다. 또한, 처음부터 숫자가 아니면 0으로 변환됩니다. 다음은 실수에 영문자, 특수 문자가 섞여있을 때의 변환 예입니다.

35.283672f → 35.283672
35.2836f72 → 35.283600
35.283672! → 35.283672
35.2836!72 → 35.283600
a35.283672 → 0.000000
!35.283672 → 0.000000
abc → 0.000000
!@# → 0.000000

단, 다음과 같이 알파벳 e를 사용하여 지수 표기법으로 된 문자열도 실수로 바꿀 수 있습니다.

ascii_string_exponential_notation_to_float.c

#include <stdio.h>
#include <stdlib.h>    // atof 함수가 선언된 헤더 파일

int main()
{
    char *s1 = "3.e5";   // "3.e5"는 문자열
    float num1;

    num1 = atof(s1);     // 문자열을 실수로 변환하여 num1에 할당

    printf("%e %f\n", num1, num1);    // 3.000000e+05 300000.000000

    return 0;
}

실행 결과

3.000000e+05 300000.000000

문자열 "3.e5"가 실수로 변환되었습니다.

만약 소수점, 지수 표기법, 소수점, 지수 표기법으로 된 문자열 "35.283672 3.e5 9.281772 7.e-5"를 4개로 잘라서 각각을 저장하고 싶을 수도 있겠죠?

그림 41‑3 여러 개의 실수로 된 문자열 변환

strtof 함수를 사용하면 여러 개의 실수로 된 문자열을 실수로 바꿀 수 있으며 함수 이름은 string to float에서 따왔습니다(stdlib.h 헤더 파일에 선언되어 있습니다).

  • strtof(문자열, 끝포인터);
    • float strtof(char const *_String, char **_EndPtr);
    • 성공하면 변환된 실수를 반환, 실패하면 0을 반환

string_to_float_multiple_real_numbers.c

#include <stdio.h>
#include <stdlib.h>    // strtof 함수가 선언된 헤더 파일

int main()
{
    char *s1 = "35.283672 3.e5 9.281772 7.e-5";    // "35.283672 3.e5f 9.2817721 7.e-5f"는 문자열
    float num1;
    float num2;
    float num3;
    float num4;
    char *end;    // 이전 숫자의 끝 부분을 저장하기 위한 포인터

    num1 = strtof(s1, &end);     // 문자열을 실수로 변환
    num2 = strtof(end, &end);    // 문자열을 실수로 변환
    num3 = strtof(end, &end);    // 문자열을 실수로 변환
    num4 = strtof(end, NULL);    // 문자열을 실수로 변환

    printf("%f\n", num1);    // 35.283672
    printf("%e\n", num2);    // 3.000000e+05
    printf("%f\n", num3);    // 9.281772
    printf("%e\n", num4);    // 7.000000e-05

    return 0;
}

실행 결과

35.283672
3.000000e+05
9.281772
7.000000e-05

s1에는 소수점으로 표기한 실수 2개와 지수 표기법으로 표기한 실수 2개가 들어있습니다. 처음에는 num1 = strtof(s1, &end);와 같이 s1을 넣어서 문자열을 실수로 변환합니다. 여기서 끝 포인터는 &end처럼 end의 메모리 주소를 넣어줍니다. 이렇게 하면 strtof 함수가 실행된 뒤에는 끝 포인터가 " 3.e5 9.281772 7.e-5"처럼 이전 숫자의 끝 부분부터 시작하게 됩니다.

두 번째부터는 num2 = strtof(end, &end);와 같이 end를 넣어주어 이전 숫자의 끝 부분부터 변환하면 됩니다. 더 이상 변환할 문자열이 없다면 num4 = strtof(end, NULL);와 같이 NULL을 넣어주면 됩니다.

참고 | 35.123456789123456789를 strtof로 변환하면?

문자열 "35.123456789123456789"를 strtof로 변환해보면 35.123455047607421875가 나옵니다(printf에서 서식 지정자를 "%.18f\n"로 지정하여 출력). 실수는 부동소수점 방식으로 저장하는데 부동소수점은 모든 실수를 정확히 표현할 수 없기 때문에 반올림을 한 뒤 근사값으로 저장합니다. 그러므로 문자열이 정확하게 변환되지 않는다고 걱정하지 않아도 됩니다.

참고 | strtod

문자열을 double형 실수로 변환하는 strtod 함수도 있는데 strtof 함수와 사용법이 같습니다. float로 선언한 변수를 double로 바꾸고 strtod 함수를 사용해보세요.

  • strtod(문자열, 끝포인터);
    • double strtod(char const *_String, char **_EndPtr);
    • 성공하면 변환된 실수를 반환, 실패하면 0을 반환