Pulling Numbers from a String – Solution

This month’s C programming exercise is to extract numbers from a string. Specifically, your task is to code the extract() function that returns the address of a digit found in a string. This function must also be capable of repeat calls to continue locating digits within the same string.

Here is my solution:

2026_02-Exercise.c

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

/* return the first location of a number
   in string s */
char *extract(char *s)
{
    static char *sp = NULL;

    /* check for recall */
    if( s != NULL )
        sp = s;
    else
    {
        /* guard against a NULL string
           passed the first time */
        if (sp==NULL)
            return(NULL);
        /* find the next non-digit */
        while( isdigit(*sp) )
            sp++;
    }

    /* find the next digit */
    while( *sp != '\0' )
    {
        if( isdigit(*sp) )
        {
            return(sp);
        }
        sp++;
    }

    return(NULL);
}

int main()
{
    char sample[] = "abc10=13!260;1m";
    char *r;
    int v;

    r = extract(sample);
    if( r != NULL )
    {
        v = atoi(r);
        printf("%d\n",v);
        while( (r=extract(NULL)) )
        {
            v = atoi(r);
            printf("%d\n",v);
        }
    }

    return 0;
}

The main() function contains a sample string to examine: "abc10=13!260;1m"

After the initial call to the extract() function, an if test checks for a NULL result. If true, the string doesn’t contain any numbers; the program is over. Otherwise, the value returned is stored in char pointer r. The atoi() function extracts this value and printf() sends it to standard output. Then a while loop repeatedly calls the extract() function to look for and output additional values until the string is exhausted:

while( (r=extract(NULL)) )

When called with NULL, the extract() function continues searching the string. The loop stops once the function returns NULL, which is why the expression is enclosed in parentheses.

The extract() function accepts the string to examine as argument *s and returns a pointer to the first digit found:

char *extract(char *s)

Within the function, static char pointer sp is initialized with the value NULL. As a static variable, the pointer’s value is maintained within the function, but it’s only initialized to NULL the first time the function is called.

The function has two parts. The first deals with a recall to the function. The second finds a digit in the string.

To check for a recall, an if-else structure is used. The if test checks whether the value of variable s (the passed pointer) is NULL:

if( s != NULL )
    sp = s;

When s is not NULL, the assumption is that the function is being called for the first time. In this instance, pointer sp is initialized to the address of s. Otherwise, the assumption is that the function is being called again and that pointer sp is already initialized.

The else part of the structure assumes that pointer sp is initialized and already references a digit in the string. (The function is being called again after initial success.) This code block’s job is to skip past any further digits in the string before looking for another digit. The while loop spins until a non-digit is found:

while( isdigit(*sp) )
    sp++;

The second part of the extract() function locates the first or next digit in the string. A while loop spins as long as the value of *sp isn’t the terminating null character:

while( *sp != '\0' )

In the loop, an if test checks to see whether *sp references a digit. If true, the address in sp is returned. Otherwise, the pointer’s address is incremented to continue looking for a digit.

When all options are exhausted, the function returns a NULL pointer.

Here’s a sample run:

10
13
260
1

The extract() function works to yank out integers from any string no matter where the digits lie within the string. This type of function is useful to extract unformatted data, such as the string generates when using ANSI commands to monitor mouse movement in a terminal window.

I hope that your solution met with success.

Leave a Reply