C Program to demonstrate the ‘atof’ and ‘gets’ functions.

Converting strings to numbers is a fundamental task in C — every value read from scanf, fgets, or command-line arguments arrives as a string and must be explicitly converted. The standard library in <stdlib.h> provides three simple conversion functions: atoi() (string to int), atol() (string to long), and atof() (string to double/float). For robust error detection, strtod() and strtol() are the preferred alternatives.

The original post used gets() — a function removed from the C11 standard because it cannot limit input size, making buffer overflow impossible to prevent. This rewrite replaces it with fgets(), which takes a maximum length argument.

String-to-Number Functions Quick Reference

Function Header Returns Detects errors?
atoi(s) stdlib.h int No — returns 0 for invalid input
atol(s) stdlib.h long No — returns 0 for invalid input
atof(s) stdlib.h double No — returns 0.0 for invalid input
strtol(s, &end, base) stdlib.h long Yes — sets end pointer, errno
strtod(s, &end) stdlib.h double Yes — sets end pointer, errno

C Program: atof, atoi, strtod, and fgets

/* String-to-number conversion in C: atoi, atol, atof, strtod
 * Demonstrates fgets() as safe replacement for gets()
 * Compile: gcc -ansi -Wall -Wextra atof_demo.c -o atof_demo */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char buf[80];
    double a, b, result;
    char *endptr;

    /* --- atof: ASCII to float (double) --- */
    printf("atof() examples:\n");
    printf("  atof(\"3.14\")   = %.6f\n", atof("3.14"));
    printf("  atof(\"-0.5\")   = %.6f\n", atof("-0.5"));
    printf("  atof(\"1.5e2\")  = %.6f\n", atof("1.5e2"));
    printf("  atof(\"abc\")    = %.6f  (non-numeric: returns 0.0)\n", atof("abc"));
    printf("  atof(\"12abc\")  = %.6f  (stops at first non-digit)\n\n", atof("12abc"));

    /* --- atoi: ASCII to int --- */
    printf("atoi() examples:\n");
    printf("  atoi(\"42\")   = %d\n", atoi("42"));
    printf("  atoi(\"-7\")   = %d\n", atoi("-7"));
    printf("  atoi(\"abc\")  = %d  (non-numeric: returns 0)\n\n", atoi("abc"));

    /* --- strtod: better than atof --- reports conversion errors --- */
    printf("strtod() with error detection:\n");
    strtod("3.14xyz", &endptr);
    printf("  strtod(\"3.14xyz\"): value=3.14, remainder=\"%s\"\n\n", endptr);

    /* --- interactive: multiply two floats with fgets (safe, not gets) --- */
    printf("Enter first number: ");
    if (fgets(buf, sizeof(buf), stdin) == NULL) return 1;
    buf[strcspn(buf, "\n")] = '\0';  /* strip trailing newline */
    a = atof(buf);

    printf("Enter second number: ");
    if (fgets(buf, sizeof(buf), stdin) == NULL) return 1;
    buf[strcspn(buf, "\n")] = '\0';
    b = atof(buf);

    result = a * b;
    printf("%.6f * %.6f = %.6f\n", a, b, result);

    return 0;
}

How to Compile and Run

gcc -ansi -Wall -Wextra atof_demo.c -o atof_demo
./atof_demo

Sample Output

atof() examples:
  atof("3.14")   = 3.140000
  atof("-0.5")   = -0.500000
  atof("1.5e2")  = 150.000000
  atof("abc")    = 0.000000  (non-numeric: returns 0.0)
  atof("12abc")  = 12.000000  (stops at first non-digit)

atoi() examples:
  atoi("42")   = 42
  atoi("-7")   = -7
  atoi("abc")  = 0  (non-numeric: returns 0)

strtod() with error detection:
  strtod("3.14xyz"): value=3.14, remainder="xyz"

Enter first number: 3.14
Enter second number: 2.0
3.140000 * 2.000000 = 6.280000

Code Explanation

  • atof() parses as far as it canatof("12abc") returns 12.0; it stops at ‘a’ because ‘a’ is not a valid float character. atof("abc") cannot parse any digit, so it returns 0.0. There is no way to distinguish “the string was 0” from “the conversion failed” using atof alone.
  • strtod() sets an end pointer — the second argument receives a pointer to the first character that was NOT converted. If endptr == original_string after the call, nothing was converted (error). If *endptr != '\0', the string had a valid number prefix followed by junk. This is the correct way to validate numeric string input.
  • fgets() vs gets()fgets(buf, sizeof(buf), stdin) reads at most sizeof(buf) - 1 characters. gets() has no length argument and will write past the end of the buffer if the user types too many characters — a classic buffer overflow. gets() was deprecated in C99 and removed in C11. Never use it.
  • Stripping the newlinefgets() includes the ‘\n’ in the buffer if it fits. buf[strcspn(buf, "\n")] = '\0' finds the first newline and replaces it with a null terminator, giving you a clean string without a trailing newline.
  • atof returns double, not float — despite the name (“ASCII to float”), atof() is declared as returning double. For float precision, cast the result: (float)atof("3.14").

What This Program Teaches

  • All external input is strings — command-line arguments, file contents, and user input via fgets all arrive as strings. Explicit conversion with atoi/atof/strtol is always required. scanf("%d") does the conversion internally but is less flexible.
  • atof/atoi do not detect errors — for validated input (form fields, config files, command-line flags), use strtol/strtod and check the end pointer. For throwaway scripts where invalid input is not a concern, atoi/atof are fine.
  • Scientific notation — atof parses “1.5e2” as 150.0 (1.5 × 10²). This is standard C floating-point string format.
  • The fgets + strcspn pattern — this is the canonical way to read a line in C safely. Memorize it: fgets(buf, n, stdin); buf[strcspn(buf, "\n")] = '\0';

Related Programs

Recommended book:
The C Programming Language — Kernighan & Ritchie (India) |
(US)
 | 
C Programming: A Modern Approach — K.N. King (India) |
(US)

Practice what you learned: C Aptitude Questions — or try our C Programming Quiz App on Android.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>