3

I know that I can scanf certain amount of numbers with scanf for example for 3 numbers

scanf("%d %d %d",array[0],array[1],array[2]);

but how can I scan it if I didn't know how many numbers (integer, not float) I would input into an array before enter (NOT EOF)? for example

input : 12 43 23(enter) --> array[0]=12, array[1]=43, array[2]=23
input : 10 20 30 40 50(enter) --> array[0]=10, array[1]=20, array[2]=30, array[3]=40, array[4]= 50
etc..

It's about how to input the numbers into an integer array.

And if it's possible, I want to save it into an 2 dimensions array, for example

input : 12 43 23(enter) --> array[0][0]=12, array[0][1]=43, array[0][2]=23
input : 10 20 30 40 50(enter) --> array[1][0]=10, array[1][1]=20, array[1][2]=30, array[1][3]=40, array[1][4]= 50
15
  • 1
    Read the whole line and parse it some other way? The fgets and strtol function can be used for this. Commented Dec 5, 2016 at 10:50
  • Wait, are you asking about how to make an array of the right size and add the numbers once you have them? Commented Dec 5, 2016 at 10:53
  • @iluvatar yes something like that, I don't know how to explain what i want properly. Commented Dec 5, 2016 at 10:55
  • so i should declare variable with [1000] ? That would be waste of memory right? Commented Dec 5, 2016 at 11:02
  • 1
    dynamic memory will be handy here. Commented Dec 5, 2016 at 11:05

3 Answers 3

1

Here is come code showing how to scan the integers into a 2D array:

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

#define INITSIZE 5
#define BUFFSIZE 1000

void print_and_free(int **array, int rowsize, int colsize);
void check_ptr(void *ptr, const char *msg);

int
main(void) {
    int **array;
    size_t rowsize = INITSIZE, colsize = INITSIZE;
    int row = 0, col, numdigits;

    char buffer[BUFFSIZE];
    char *number;

    array = malloc(rowsize * sizeof(*array));
    check_ptr(array, "Allocation");

    printf("Enter digits(Enter blank line to end):\n");
    while (fgets(buffer, BUFFSIZE, stdin) != NULL && strlen(buffer) != 1) {
        col = 0;
        numdigits = 0;
        if (rowsize == row) {
            rowsize *= 2;
            array = realloc(array, rowsize * sizeof(*array));
            check_ptr(array, "Reallocation");
        }

        array[row] = malloc(colsize *sizeof(int));
        check_ptr(array[row], "Allocation");

        number = strtok(buffer, " ");
        while (number != NULL) {
            numdigits++;
            if (colsize == numdigits) {
                colsize *= 2;
                array[row] = realloc(array[row], colsize * sizeof(int));
                check_ptr(array[row], "Reallocation");
            }
            array[row][col] = atoi(number);
            col++;
            number = strtok(NULL, " ");
        }
        row++;
    }

    print_and_free(array, row, col);

    return 0;
}

void
print_and_free(int **array, int rowsize, int colsize) {
    int row, col;

    printf("Your numbers:\n");
    for (row = 0; row < rowsize; row++) {
        for (col = 0; col < colsize; col++) {
            printf("array[%d][%d] = %d", row, col, array[row][col]);
            if (col != colsize - 1) {
                printf(", ");
            }
        } 
        free(array[row]);
        array[row] = NULL;
        printf("\n");
    }

    free(array);
}

void
check_ptr(void *ptr, const char *msg) {
    if (!ptr) {
        printf("Unexpected null pointer: %s\n", msg);
        exit(EXIT_FAILURE);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, by the way what size_t rowsize = INITSIZE, colsize = INITSIZE; for?
No worries @juliussin. Yeah they are just starting sizes to allocate space from malloc. I just assumed 5 would be a good starting size, and if your arrays end up being bigger, then just realloc more space. You can replace size_t with int if you want, that might be clearer for you.
1

Here's how you can store things in a (dynamically allocated) array. This does assume that the line length is limited to 1000 chars though. (Code adapted from How do I use scanf() to take an arbitrary amount of integers?)

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

int main() {
    int val_size = 2;
    int* vals = (int*)malloc(val_size * sizeof(int)); // initial array size
    char buffer[1000]; // for reading in the line
    int pos, bytes_read, num;
    int num_read = 0;

    if (fgets(buffer, sizeof(buffer), stdin) != 0) {
        for (pos = 0; sscanf(buffer+pos, "%d%n", &num, &bytes_read) != EOF; pos += bytes_read) {
            // resize the array if needed
            if (num_read >= val_size) {
                val_size *= 2;
                vals = (int*)realloc(vals, val_size * sizeof(int));
            }

            // store the value in the array
            vals[num_read] = num;
            num_read++;
        }
    }

    // print the values to prove it works
    for (int i = 0; i < num_read; i++) {
        printf("%d ", vals[i]);
    }
    printf("\n");

    free(vals); // important after you're done with it
}

You can wrap a while around the if to get multiple lines.

9 Comments

you should not cast return value from malloc/realloc. stackoverflow.com/questions/605845/…
This seems like a religious war, yes? Or at least in the same vein as if (a == 0) vs if (0 == a)? Perhaps strictly speaking it alleviates some user error, there are pros and cons both ways.
stackoverflow.com/a/14879184/3761456 Granted, it's got a tenth the upvotes of the top one, yet they're there and it seems mostly stylistic to me at this point.
Honeslty speaking int *vals = malloc(val_size * sizeof *vals); looks less cluttered than int* vals = (int*)malloc(val_size * sizeof(int));
@lluvatar i dont buy that. this question is marked C, not C++. If you are using malloc in C++ you are definitely doing something wrong.
|
0

You may use a while loop and check for the return value of scanf. For example:

int num = 0;
int idx = 0;
int arr[100] = { 0 };
while( scanf( "%d", &num ) == 1 )
{
    arr[idx++] = num;
    if( idx == 99 )  // protect from array overflow
    {
        break;
    }
}
for( int i = 0; i < idx; i++ )
{
    printf( "%d\n", arr[i] );
}

4 Comments

I don't think this does what they want... it doesn't scan multiple ints on a line.
@Iluvatar yes it does
No, although it scans multiple integers on one line. it does not terminate on "Enter (NOT EOF)" as requested.
Ah, it does, but you have to enter something that causes scanf to unblock, so just hitting enter doesn't do it.

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.