Reputation: 21
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?
Upvotes: 2
Views: 3531
Reputation: 689
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;
}
Upvotes: 0
Reputation: 677
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.
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.
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:
malloc()
.scanf()
until the end of the input or until the array is full.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).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.
Upvotes: 4