1

I'm working on a project for my class and have come upon a roadblock. Let's say I have a space separated character array (string) that contains numbers (each followed by a space character). Assume it looks something like this:

0 1 15 10 6 2

The number of items in it will never be constant so I cannot use sscaf() to get all the numbers. I tried looping trough it as characters but I ended up separating the double digit numbers messing things up.

Can someone guide me on how I can get each number in the string and save it to a int array without separating the double digit ones? I'm writing this in C

Thanks in advance

miiguell
  • 69
  • 6
  • You'd need two pointers, a head and a tail. Move the tail until you hit an empty space, then subtract the tail from the head and allocate a new char * then add all the characters from head to tail into the new char * - do this until tail is at the end of the string – Vio Ariton Nov 29 '19 at 19:15
  • You can loop over an unkown number of numbers with the help of `sscanf()`s return value. Just don't follow the common malpractice to ignore it. – Yunnosch Nov 29 '19 at 19:32

2 Answers2

0

how I can get each number in the string and save it to a int array without separating the double digit ones?

  1. Scan the string once to find the number of int
  2. Define the array
  3. Scan again and save into the array

...

const char *s = "0 1 15 10 6 2 ";
int count = scans_ints(s, NULL);
if (count <= 0) Handle_Bad_intput();
else {
  int arr[count];
  sscan_ints(s, arr);
}

Possible sscan_ints() (untested)

#include <ctype.h>
#include <limits.h>

int sscan_ints(const char *s, int *arr) {
  int count = 0;
  for (;;) {
    // Consume leading spaces: ease detection of end-of-line
    while (isspace((unsigned char) *s)) s++;
    if (*s == '\0') break;
    char *endptr;  // Location where conversion ended
    errno = 0;
    long num = strtol(s, &endptr, 10);
    if (s == endptr) return -1;  // non-numeric text
    if (errno || num < INT_MIN || num > INT_MAX) return -1; // number too big
    if (arr) {
      arr[count] = (int) num;
    }
    count++;
    s = endptr;
  }
  return count;
}  
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Another solution to your problem would be to navigate through the string and add the characters into a buffer until you hit an empty space, then have a function that takes that buffer and converts it into a number.

But before that we have to count the number of empty spaces, since that will tell us the number of integers we have, or you could have a default value for the array of integers and realloc when there are more numbers than the default value.

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

#define WHITE_SPACE (0x20)


int32_t
get_len_numbers(const char *str) {

    int32_t     n;
    const char *ptr;

    ptr = str;
    n   = 0;

    for(; *ptr != 0; ++ptr)
        n += (*ptr == ' ');

    return(n + 1);

}

int32_t
stoi(const char *number) {

    int32_t n;

    n = 0;

    for(; *number != 0; ++number)
        n = (n * 10) + (*number & 0x0F);

    return(n);

}


int main(void) {

    int32_t           len;
    register int32_t  i;
    register int32_t  j;

    uint8_t           buf[32];
    char              *str;

    int32_t           *numbers;

    str     = "1 5 25 30 99";

    len     = get_len_numbers(str);
    numbers = malloc(sizeof(int) * len);

    if(numbers == NULL)
        exit(EXIT_FAILURE);

    for(i = 0, j = 0; ; ++str) {

        if(*str == WHITE_SPACE || *str == 0) {

            buf[i] = 0;

            numbers[j++] = stoi(&buf[0]);

            i = 0;

            if(*str == 0)
                break;

        } else {

            buf[i++] = *str;

        }


    }

    return(0);
}
Vio Ariton
  • 407
  • 1
  • 5
  • 17