Parsing the execution line in C

I have the following character string:

"..1....10..20....30...40....50...80..." 

and I need to extract all the numbers from it into an array.

What is the best way to do this in C?

+5
source share
4 answers

Perhaps the easiest way is to use a function strtok()(or strtok_r()if there is a problem with the reentrant):

char str[] = "..1...10...20";
char *p = strtok(str, ".");
while (p != NULL) {
    printf("%d\n", atoi(p));
    p = strtok(NULL, ".");
}

Once you get the results of the call atoi(), it would be easy to store these integers in an array.

+11
source

You can use the sscanf code with suppressed assignment (% * [.]) To skip periods (or any other character you want), and the scanned character counter code% n to advance the line pointer.

const char *s = "..1....10..20....30...40....50...80...";
int num, nc;

while (sscanf(s, "%*[.]%d%n", &num, &nc) == 1) {
    printf("%d\n", num);
    s += nc;
}
+4

, , , undefined, , , .. , , , , , while. , , , , , .

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

#define ARRAY_SIZE 10

size_t store_numbers (const char *s, long *array, size_t elems)
{
  /* Scan string s, returning the number of integers found, delimited by
   * non-digit characters.  If array is not null, store the first elems
   * numbers into the provided array */

  long value;
  char *endptr;
  size_t index = 0;

  while (*s)
  {
    /* Skip any non-digits, add '-' to support negative numbers */
    while (!isdigit(*s) && *s != '\0')
      s++;

    /* Try to read a number with strtol, set errno to 0 first as
     * we need it to detect a range error. */
    errno = 0;
    value = strtol(s, &endptr, 10);

    if (s == endptr) break; /* Conversion failed, end of input */
    if (errno != 0) { /* Error handling for out of range values here */ }

    /* Store value if array is not null and index is within array bounds */
    if (array && index < elems) array[index] = value;
    index++;

    /* Update s to point to the first character not processed by strtol */
    s = endptr;
  }

  /* Return the number of numbers found which may be more than were stored */
  return index;
}

void print_numbers (const long *a, size_t elems)
{
  size_t idx;
  for (idx = 0; idx < elems; idx++) printf("%ld\n", a[idx]);
  return;
}

int main (void)
{
  size_t found, stored;
  long numbers[ARRAY_SIZE];
  found = store_numbers("..1....10..20....30...40....50...80...", numbers, ARRAY_SIZE);

  if (found > ARRAY_SIZE)
    stored = ARRAY_SIZE;
  else
    stored = found;

  printf("Found %zu numbers, stored %zu numbers:\n", found, stored);
  print_numbers(numbers, stored);

  return 0;
}
+1

I prefer using strtok in a for loop. Makes this more natural, although the syntax looks a bit strange.

char str[] = "..1....10..20....30...40....50...80..."
for ( char* p = strtok( strtok, "." ); p != NULL; p = strtok( NULL, "." ) )
{
    printf( "%d\n", atoi( p ) );
}
-2
source

All Articles