-2

So i have this example:

3 4 6 11 4 6 38 7 6 9

I need to get from user several numbers and create multi dimension array.

The first number N (3 in my example) mean that my array (or matrix) will contain value and insert all this numbers (the next 9 values) into my array.

So first i need to define the array according my first value (3 in my example) and create my array:

int a[3][3];

The catch here is that i need to get all my input in a single line so i cannot use this:

int marks[3];
int i;

for(i=0;i<3;i++)
{
    printf("Enter a no\n");
    scanf("%d",(marks+i));
}
ManmeetP
  • 801
  • 7
  • 17
Dana Yeger
  • 617
  • 3
  • 9
  • 26
  • 1
    The code doesn't match your task. But still, `scanf("%d", ...` WOULD work, it doesn't care **which** whitespace separates the numbers. Space works just as well as newlines. I would strongly suggest not to use `scanf()` though, see my [beginners' guide away from `scanf()`](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html). –  Nov 20 '17 at 09:19
  • Not advisable, but [proof of concept for my previous comment](https://ideone.com/loH26r) –  Nov 20 '17 at 09:23
  • Why can't you use a [3][3] array and a nested loop? The input format shouldn't matter. – Lundin Nov 20 '17 at 09:27
  • user @Lundin can you post short simple ? – Dana Yeger Nov 20 '17 at 09:32
  • @DanaYeger see my comment above (including a link to example code)! Right now, it's **unclear what you're asking** because an approach with `scanf("%d", ...)` **will** work regardless of how the input is formatted, so your sample code adapted to a 2d-array does what you want. –  Nov 20 '17 at 09:33
  • int m[dim][dim]; got an compiler error: expression must have a constant value – Dana Yeger Nov 20 '17 at 09:44
  • @DanaYeger Then your compiler doesn't support variable length arrays. That either means it's very antique, or it's an exotic incarnation of some stripped-down C11 compiler. Use a decent compiler or allocate a flat array with `malloc()` and calculate the indices yourself. –  Nov 20 '17 at 09:47
  • @DanaYeger [equivalent code without VLA](https://ideone.com/KkFPvY) -- but I'd really suggest you get a better compiler, supporting C11 **with** VLAs. –  Nov 20 '17 at 09:50
  • I am using ubuntu usually it just now (only now) that i am on VS2017 – Dana Yeger Nov 20 '17 at 10:15
  • @DanaYeger Microsoft doesn't have a decent / modern C compiler. When you're on Windows, my recommendation would be to install `gcc` or `clang` using [MSYS2](http://www.msys2.org/). –  Nov 20 '17 at 10:22
  • I wasn't going to answer this but the current answers are teaching bad practice. I have posted an answer with the 4 possible ways to allocate a 2D array: statically, as a VLA, as a dynamic 2D array or as a dynamic "mangled" 2D array (old style). – Lundin Nov 21 '17 at 14:24

3 Answers3

0

scanf reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments.

scanf will store whole the input from stdin, so it really does not matter if it is in single line or not. The way for your code is just, simply ask user for dimensions and create the variable of the given dimension and fill each value with a scanf.

There are 3 ways to do it :

  1. If your compiler supports variable length array:

    int size,i,j;
    scanf("%d",&size);
    
    int matrix[size][size];
    
    for(i=0;i<size;i++)
    {
        for(j=0;j<size;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    
  2. Does not support variable length array: (using array of pointers)

    int size,i,j;
    scanf("%d",&size);
    
    int **matrix;
    matrix = (int **)malloc(sizeof(int *) * size);
    
    for(i=0;i<size;i++)
    {
        matrix[i] = (int *)malloc(sizeof(int) * size);
    }
    
    for(i=0;i<size;i++)
    {
        for(j=0;j<size;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    

    This looks easy but the way is very poor as it is not actually an 2D array but an array of pointers. hence, I suggest to use the 3rd way if your compiler does not support variable length array.

  3. Using malloc: (with pointer)

    Create Array of integers like:

    int size;
    scanf("%d",&size);
    int *matrix;
    matrix = (int *) malloc( sizeof(int) * size * size );
    

    Now, to fill or get the values of the Array you need to traverse to the particular value.

    to fill:

     for(i=0;i<size;i++)
     {
        for(j=0;j<size;j++)
        {
            scanf("%d", (matrix + i*(size) + j));
        }
     }
    

    to iterate: (print in this case)

     for(i=0;i<size;i++)
     {
        for(j=0;j<size;j++)
        {
            printf("%d " ,*(matrix+ i*size + j) );
        }
        printf("\n");
     }
    

Note: It is very important to constrain the input and check whether it lies in some fixed range or not. for ex: ( 0 < size < 100). It is very simple and you can do it yourself. I have answered the important parts only :)

Jay Joshi
  • 868
  • 8
  • 24
  • Please don't teach the pointer-to-pointer method. It is inefficient, dangerous, needlessly complex and there is no reason to use it here. [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Lundin Nov 21 '17 at 14:25
  • well, He is probably solving his homework example. I wonder how dangerous could it be to him.!? and It is easiest way to define the 2D array. instead of iterating like (pointer * y) + x .! – Jay Joshi Nov 21 '17 at 14:30
  • 1) Try using memcpy on the "array" in your 2nd example and you'll see just how dangerous. 2) We should not teach methods that are always incorrect for any purpose, be it for homework or for launching a space shuttle. 3) You second example _is not even a 2D array_. 4) Agreed that such code is ugly - but it was the only way back in C90. In modern C, we should use dynamically allocated 2D arrays instead. – Lundin Nov 21 '17 at 14:35
  • I request to check the updated answer. @Lundin sorry, It was really a bad way to answer, I really apologize for my answer and behavior. – Jay Joshi Nov 21 '17 at 15:02
  • Still there's no reason to use the pointer to pointer. I posted an answer which shows how to allocate a 2D array dynamically. – Lundin Nov 21 '17 at 15:06
-1

To begin with, you can't store 10 numbers in a 3x3 matrix. Always make sure your specification makes sense before you start programming.

Taking the input is trivial, just use a nested loop to control where the read input ends up in your matrix. Example with a fixed array size:

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

#define x 3
#define y 3

int main (void)
{
  int arr[x][y];

  printf("Enter %d numbers: ", x*y);

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      scanf(" %d", &arr[i][j]);
    }
  }

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      printf("%d ", arr[i][j]);
    }
    printf("\n");
  }

  return 0;
}

(Note that this leaves a whole lot of junk like line feed characters behind in stdin. There's also no buffer overflow protection. See How to read / parse input in C? The FAQ for examples of how to read input properly.)


If you need a variable size matrix, you can use variable length arrays (VLA):

size_t x = 3; // some run-time value
size_t y = 3; // some run-time value
int arr[x][y];
... // then same code as above

Alternatively, you can use a dynamically allocated 2D array:

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

int main (void)
{
  size_t x = 3;
  size_t y = 3;
  int (*arr)[y] = malloc( sizeof(int[x][y]) );

  printf("Enter %zu numbers: ", x*y);

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      scanf(" %d", &arr[i][j]);
    }
  }

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      printf("%d ", arr[i][j]);
    }
    printf("\n");
  }

  free(arr);

  return 0;
}

Alternatively, if your compiler is from the Jurassic period, you can use old style "mangled" 2D arrays:

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

int main (void)
{
  size_t x = 3;
  size_t y = 3;
  int* mangled = malloc(x * y * sizeof *mangled);

  printf("Enter %zu numbers: ", x*y);

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      scanf(" %d", &mangled[i*x + j]);
    }
  }

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      printf("%d ", mangled[i*x + j]);
    }
    printf("\n");
  }

  free(mangled);

  return 0;
}

The above 4 alternatives are the only alternatives. You should not use "pointer-to-pointer look-up tables", there is absolutely no need for them here. Unfortunately, lots of bad books and bad teachers spread that technique. See Correctly allocating multi-dimensional arrays.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Please read the question, It says the first integer in input is the size of the matrix. It is not fixed from the start what would be the size. and to be honest, I am beginner at C. I did not understand 2 of your way to allocate 2D arrays dynamically. – Jay Joshi Nov 21 '17 at 15:12
  • @JayJoshi 1st snippet shows how to do it statically at compile time, 2nd shows how to do it in runtime with VLA, 3rd shows how to do it with in runtime with dynamic memory allocation of a 2D array, and the 4th method is how the dinosaurs used to do it. – Lundin Nov 21 '17 at 15:18
-3

Try this:

int** InitMatrix()
{
    int** matrix = NULL;

    int n;
    if (scanf("%d", &n) > 0 && n > 0)
    {
        matrix = malloc(n * sizeof(int*));
        for (int i = 0; i < n; i++)
        {
            matrix[i] = malloc(n * sizeof(int));
            for (int j = 0; j < n; j++)
            {
                if (scanf("%d", &matrix[i][j]) == 0)
                {
                    // user input error; decide what to do here
                }
            }
        }
    }
    else
    {
        // user input error; decide what to do here
    }

    return matrix;
}
goodvibration
  • 5,980
  • 4
  • 28
  • 61
  • @FelixPalmen: Because the question says "I need to get from user several numbers and create **multi dimension array**" – goodvibration Nov 20 '17 at 09:50
  • You're aware that a multi dimensional array is **not** an array of pointers? –  Nov 20 '17 at 09:51
  • @FelixPalmen: Well, that's as close as you can get if you want its dimensions to be set during runtime (unless you're willing to use VLA, but that's not supported in the basic C standard if I remember correctly). – goodvibration Nov 20 '17 at 09:52
  • IBTD. The *closest* you can get is a flat array with explicit index calculations, as this is what a compiler would make from a real multidimensional array anyways. VLAs not being required in C11 is something to be aware of, but still a compiler supporting C11 without VLAs would be quite exotic. VLAs were mandatory in C99. –  Nov 20 '17 at 09:55
  • @FelixPalmen: Second thing, your first comment (which asks why to use a double pointer) doesn't quite "align" with your second comment (which asks why to use pointers at all). So I'm inclined to interpret your meaning as "use `int* matrix`". That is also an option, but I think that when this dude says "multidimensional", then that's what he means. A matter of interpretation I suppose. – goodvibration Nov 20 '17 at 09:56
  • [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – Lundin Nov 20 '17 at 10:10
  • @goodvibration nope, my point is, without VLA support, you can't get a multi-dimensional array of variable size from `malloc()`, so you already dropped that requirement. Then, using an array of pointers is just wasteful and easily confuses newcomers to think a multi-dimensional array actually **is** an array of pointers -- you see that happen far too often. –  Nov 20 '17 at 10:21
  • @FelixPalmen: Let's start with your notion that "this is what a compiler would make from a real multidimensional array anyways". The memory image of a statically allocated multidimensional array and a dynamically allocated "single-pointer" array is indeed the same - a contiguous chunk of the actual values (integers in this case), whereas my method above yields a non-contiguous chunk of the actual values. However, let's consider the "multidimensional array" requirement for a second - is the question poster looking for the same "memory image", or is he looking for the same "coding behavior"? – goodvibration Nov 20 '17 at 15:45
  • i.e., will he later be able to access the array via "multidimensional indexing", for example, `matrix[i][j]`? The answer is no when using a "single-pointer" array as you have suggested, and yes when using a "double-pointer" array as I have suggested. Of course, my method is missing the part of returning the array dimension, which is definitely required outside the function in order to ensure legal access, and in order to dellocate the array correctly. The question poster can fill in for that missing part. – goodvibration Nov 20 '17 at 15:45
  • 1
    Our debate of which type of allocation really depends on the exact requirements in the question, which as I said before, appears to be a matter of interpretation. – goodvibration Nov 20 '17 at 15:46
  • @goodvibration If you read the link I posted, you'll get an explanation why the pointer to pointer is 100% bad practice in this case. The only use for a pointer-to-pointer based look-up table is when you need dimensions of individual sizes, such as when declaring an array of pointers to strings. Which is not useful in this case. – Lundin Nov 21 '17 at 13:57