2

How can I read integers from the standard input and store them in an array? I do not know in advance how many integers I will have to read from the standard input.

Examples of input:

4 5 6 7 8

(or)

4,5,6,7,8 

(or)

4
5
6
7
8

Example of output: Just print that array.

In Python I can do it this way:

arr = list(map(int,input().split(' ')))

In Python it is easy because I do not need to specify the size of the array beforehand. How can I read integers from the input and store them into an array in this way in C? Is it possible?

3
  • 1
    Depends - if it's taken as a string, then it's possible straightaway. Other types, it's possible but not easy. Commented Dec 4, 2020 at 9:58
  • Both languages have shortcomings: you certainly can do this in C, but it is somewhat tedious. As for Python, calling an array a list is fostering a whole generation of confused programmers. Shame on GVR. Commented Dec 4, 2020 at 10:51
  • Does this answer your question? Read from standard input into a C array Commented Dec 4, 2020 at 12:47

2 Answers 2

4

The main issue here is to create an array wide enough to store all the integers contained in the standard input, but we don't know how many values we are going to read.

The input is a file on the Hard Disk Drive

If you read from a file, you can afford to read the file twice: the first time, you do not store the values, you just count how many values there are; the second time, you allocate an array with the right size with malloc() and you store the integers into the array.

The input is read from the standard input

On the other hand, if you read from the standard input, you can't read the input twice, because it is consumed as soon as you read it. So you need to compute the size of the array and store the elements in the array at the same time. To do this, you begin by allocating an array of size 10, then you read 10 values from the standard input, and if the array is not big enough, you allocate another one bigger, you copy the values read so far from the first array into the second array, you delete the first array, and you continue to do this until all the input is exhausted.

Here is the algorithm:

  1. Allocate an array of 10 integers with malloc().
  2. Read integers from the standard input with scanf() until the end of the input or until the array is full.
  3. If there are no more integers to read from the standard input, stop.
  4. Otherwise, use the function realloc() to double the size of the array, and go back to step 2. The realloc() function will potentially allocate a second array with the new size, copy the integers from the first array into the first half of the second array (this will happen if there is not enough free space after the end of the first array to expand it).

If it is too difficult

It is not a one-liner like in Python. Doing this correctly is actually quite hard for a beginner. If you struggle too much, just dump the standard input into a temporary file on the hard disk drive, and use the trick of reading the file twice.

If the input is produced by something you control, you could also try to change the format of the input. For instance, if you add the number of values that need to be read as the first element of the input, it will simplify your task.

Sign up to request clarification or add additional context in comments.

7 Comments

I am sorry I didn't get that can u explain briefly by code.
@RalphS, you can also mention for reading input in the form of 4,5,6,7,8 we need to use functions like fgets
@UDAY Yes I will add a more verbose explanation.
@UDAY, They key is that you need to keep track of 1) how many elements the array can currently accommodate, and 2) How many elements of the array are currently populated. Most of the time, you will have some elements that have been allocated, but aren't actually in use. Python does this under the covers for you.
@UDAY Is it clear enough, or do you need an even more verbose explanation?
|
0

The (most) flexible solution is to use dynamic linked list (it still has properties of array where you can iterate/traverse over it). On below sample, you can find two(2) scenarios using linked list where on scenario #1, user provide the input once using comma delimited list of integer; while for scenario #2, user will be prompted until a certain input is provided.
Sample output:

=== Scenario 1 ===
Enter comma delimited integer (e.g. 1,2,3,4): 1,6,8,9
=Print List=
1
6
8
9

=== Scenario 2 ===
Enter integer (-99 to stop): 3
Enter integer (-99 to stop): 4
Enter integer (-99 to stop): 5
Enter integer (-99 to stop): 6
Enter integer (-99 to stop): 7
Enter integer (-99 to stop): -99
=Print List=
3
4
5
6
7

Sample Code:

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

struct Element
{
    int data;
    struct Element *next;
};

void printList(struct Element *list) {
    printf("=Print List=\n");
    while(list != NULL) {
        printf("%d\n", list->data);
        list = list->next;
    } //end while
}

int main(void) {
    /* 1. This is for the case where input from user is expected to be once and is using comma delimited.
    Data will be stored on a dynamic linked list.
    Note: input is not validated. */
    char str1[256];
    char delimiter[2] = "," ;
    struct Element *listResult = NULL; //this is to store the result list
    struct Element *lastElement=NULL;

    printf("=== Scenario 1 ===\n");
    printf("Enter comma delimited integer (e.g. 1,2,3,4): ");
    scanf("%s", str1);
    char *token = strtok(str1, delimiter);

    //Parse the input and put into the linked list
    while(token != NULL ) {
        int intData = atoi(token);
        struct Element *newElmt = (struct Element *) malloc (sizeof(struct Element));
        newElmt->data = intData;
        newElmt->next = NULL;

        if (listResult == NULL) { //listResult is initially empty, put the new element as the head
            listResult = newElmt;
            lastElement = newElmt;
        } else { //listResult is NOT empty, put the new element as the tail
            lastElement->next = newElmt;
            lastElement = newElmt;
        } //end if
        token = strtok(NULL, ",");
    } //end while
    printList(listResult);

    /* 2. This is for the case where input from user is expected to be multiple times until specific input is provided (i.e. -99).
    Data will be stored on a dynamic linked list.
    Note: input is not validated. */
    int inputInt=0;
    struct Element *listResult2 = NULL; //this is to store the result list
    struct Element *lastElement2 = NULL;

    printf("\n=== Scenario 2 ===\n");
    do {
        printf("Enter integer (-99 to stop): ");
        scanf("%d", &inputInt);

        if (inputInt != -99) {
            struct Element *newElmt = (struct Element *) malloc (sizeof(struct Element));
            newElmt->data = inputInt;
            newElmt->next = NULL;

            if (listResult2 == NULL) { //listResult2 is initially empty, put the new element as the head
                listResult2 = newElmt;
                lastElement2 = newElmt;
            } else { //listResult2 is NOT empty, put the new element as the tail
                lastElement2->next = newElmt;
                lastElement2 = newElmt;
            } //end if
        } //end if
    } while (inputInt != -99);
    printList(listResult2);

    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.