user12174294
user12174294

Reputation:

How can I extract an integer from within a string?

I'm working on an assignment and as part of it I need to extract the integer from a string.

I've tried using the atoi() function, but it always returns a 0, so then I switched up to strtol(), but it still returns a 0.

The goal is to extract the integers from the string and pass them as arguments to a different function. I'm using a function that then uses these values to update some data (update_stats).

Please keep in mind that I'm fairly new to programming in the C language, but this was my attempt:

void get_number (char str[]) {
    char *end;
    int num;
    num = strtol(str, &end, 10);
    update_stats(num);
    num = strtol(end, &end, 10);
    update_stats(num);
}

The purpose of this is in a string "e5 d8" (for example) I would extract the 5 and the 8 from that string.

The format of the string is always the same.

How can I do this?

Upvotes: 8

Views: 1251

Answers (3)

kesarling
kesarling

Reputation: 2216

I suggest you write the logic on your own. I know, it's like reinventing the wheel, but in that case, you will have an insight into how the library functions actually work.

Here is a function I propose:

bool getNumber(str,num_ptr)
char* str;
long* num_ptr;
{
    bool flag = false;
    int i = 0;
    *num_ptr = 0;
    char ch = ' ';
    while (ch != '\0') {
        ch = *(str + i);
        if (ch >= '0' && ch <= '9') {
            *num_ptr = (*num_ptr) * 10 + (long)(ch - 48);
             flag = true;
        }
        i++;
    }
    return flag;
}

Don't forget to pass a string with a \0 at the end :)

Upvotes: 0

Eraklon
Eraklon

Reputation: 4288

If the format is always like this, then this could also work

#include <stdio.h>

int main()
{
    char *str[] = {"a5 d8", "fe55 eec2", "a5 abc111"};
    int num1, num2;

    for (int i = 0; i < 3; i++) {
      sscanf(str[i], "%*[^0-9]%d%*[^0-9]%d", &num1, &num2);
      printf("num1: %d, num2: %d\n", num1, num2);
    }
    return 0;
}

Output

num1: 5, num2: 8                                                                                                                                                                   
num1: 55, num2: 2                                                                                                                                                                  
num1: 5, num2: 111

%[^0-9] will match any non digit character. By adding the * like this %*[^0-9] indicates that the data is to be read from the string, but ignored.

Upvotes: 1

rici
rici

Reputation: 241721

strtol doesn't find a number in a string. It converts the number at the beginning of the string. (It does skip whitespace, but nothing else.)

If you need to find where a number starts, you can use something like:

const char* nump = strpbrk(str, "0123456789");
if (nump == NULL) /* No number, handle error*/

(man strpbrk)

If your numbers might be signed, you'll need something a bit more sophisticated. One way is to do the above and then back up one character if the previous character is -. But watch out for the beginning of the string:

if ( nump != str && nump[-1] == '-') --nump;

Just putting - into the strpbrk argument would produce false matches on input like non-numeric7.

Upvotes: 7

Related Questions