Search code examples
carraysc-stringsstrtol

Store string with numbers as an integer array


I'm writing a program in C where there's a user input. This input is a string with integer values separated by a space. The numbers (except the first one) have to be stored in an integer array. The first number indicates how many numbers have to be stored (so the size of the array).

What's the easiest way to do this in C? Here's an example:

input--> "5 76 35 95 14 20"

array--> {76, 35, 95, 14, 20}

I've been searching around but I can't find a solution to my question. At the moment, I've tried to store the values of the input in a char array and, when there's a space, I convert this string to an integer using atoi() and I add it to the integer array. But it prints strange values. This is the code:

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

int main()
{
    char text[10];
    scanf("%s", text);

    int nums[4];
    int indNs = 0;

    char lastNum[10];
    int indLN = 0;

    for(int i = 0; i < 10; i++)
    {
        if(text[i] == ' ')
        {
            nums[indNs] = atoi(lastNum);
            indNs++;

            sprintf(lastNum, "%s", "");
            indLN = 0;
        } else
        {
            lastNum[indLN] = text[i];
            indLN++;
        }
    }

    nums[indNs] = atoi(lastNum);

    for(int i = 0; i < 4; i++)
    {
        printf("%d\n", nums[i]);
    }
}

Solution

  • You cannot use scanf to read space separated input as scanf will stop reading once it hits white space.

    scanf("%s", text); //Wrong, always reads only first number.
    

    You could use fgets followed by sscanf with %n in loop.

    char buf[100];
    
    int *array = NULL;
    int numElements = 0;
    int numBytes = 0;
    if (fgets(buf, sizeof buf, stdin)) {
    
       char *p = buf;
       if (1 == sscanf(buf, "%d%n", &numElements,&numBytes)){
           p +=numBytes;
           array = malloc(sizeof(int)*numElements);
           for (int i = 0;i<numElements;i++){
             sscanf(p,"%d%n", &array[i],&numBytes);
             p +=numBytes;
             printf("%d,", array[i]);
           }
       }
    }
    

    %n returns number of bytes read so far thus advance the buf number of bytes read so far.


    If you are not dealing with strings and directly reading from stdin you don't need all that mess.

    int *array = NULL;
    int numElements = 0;
    
    
    scanf("%d", &numElements);
    array = malloc(sizeof(int)*numElements);
    
    for(int i=0;i<numElements;i++)
    {
        scanf("%d", &array[i]);
        printf("%d ", array[i]);
    }