0

I'm trying to make a program in C that transfers a 2-dimensions-array(a matrix to be particular) into a single-dimension-array. For example, if we have a matrix with L lines and C columns, it should turn into a a single line newL=L*C. Therefore, if the matrix has 3 lines and 4 columns, the new array will have 3*4=12 as its size.

The matrix should turn to this:

1 2
     --> 1 2 3 4
3 4 

The problem I'm facing right now, is how to assign the matrix to the array without having random values or repeated values.

The piece of code I'm concerned with, goes like this:

for(k=1;k<=t;k++)
    {
        for(i=1;i<=l;i++)
        {
            for(j=1;j<=c;j++)
            {
                v[k]=m[i][j];
            }
        }
    }

k,i and j are counters of the matrix(2-dimensions-array) and the the array. two of which; i and j, are counters for the matrix and k is the array's counter. Notice that each one of them starts from 1 and goes to its size and in this size I will use 2 lines and 2 columns for the matrix therefore the array will have a size of 4(2*2).

  • l is the number of lines in the array.
  • c is the number of colunms in the array.
  • t is the size of the array. t=l*c

Executing the code gives me this as a return:

1 2
    --> 4 4 4 4
3 4

Simply said, the piece of code will ALWAYS give the last value of the matrix to the array. So if I replace 4 with 5 in the matrix, the array will have 5 5 5 5.

EDIT:

Here is the full code to understand what I'm trying to do:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int c,i,j,l,k,t;
    printf("Donner le nombres des lignes: ");
    scanf("%d",&l);
    printf("Donner le nombres des colonnes: ");
    scanf("%d",&c);
    int m[l][c];
    t=l*c;
    int v[t];
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("Donner m[%d][%d]: ",i+1,j+1);
            scanf("%d",&m[i][j]);
        }
    }
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("%d\t",m[i][j]);
        }
        printf("\n");
    }
    printf("\n\n\n\n");
    for(k=1;k<=t;k++)
    {
        for(i=1;i<=l;i++)
        {
            for(j=1;j<=c;j++)
            {
                v[k]=m[i][j];
            }
        }
    }
    for(k=0;k<t;k++)
    {
        printf("%d\t",v[k]);
    }
    system("pause");
}

Thank you guys for the help, I found the correct way to do it.

Amine
  • 1,396
  • 4
  • 15
  • 32
  • Do not use letters which can easily be confused with digits! Here, I assume you mean the letter `l` (lower case "ell"). – too honest for this site Nov 17 '15 at 00:57
  • @Olaf it's a bad habbit. You told me that yesterday and I still use it. Sorry. Yes, I mean lower case L with l. – Amine Nov 17 '15 at 01:06
  • Get rid of that Hobbit - ehm habit - asap. The longer you keep it, the harder it will become. Also get rid of indexing arrays from `1`. Most programming languages use zero-based array-indexes. Anything else just confuses and may keep the compiler from optimizing the program. – too honest for this site Nov 17 '15 at 12:06
  • Dont edit saying you found the correct way to do it! Mark one of the answers correct, or if you found a better way add your own answer! – Fantastic Mr Fox Nov 17 '15 at 16:47
  • @Ben Thanks for the tip, it's done. – Amine Nov 21 '15 at 14:39

6 Answers6

1
  1. You need not the outer loop
  2. Array indices are zero-based in C

Thus, we have:

    for(k = 0, i = 0; i < o; i++)
    {
        for(j = 0; j < p; j++)
        {
            v[k++] = m[i][j];
        }
    }

where o and p - dimensions of the matrix m

Serge
  • 6,088
  • 17
  • 27
1

If we have a multidimensional array like this:

int nums[3][3];

And we have:

int all[9];

And we've got:

int a, b;

We'll reference each of the nums like this:

nums[a][b];

Now think of what the values of a and b will actually be:

for (a = 0; a < 3; a++) {
   for (b = 0; b < 3; b++)
      all[((a * 3) + b)] = nums[a][b];
}

This will work so long as you multiply a with the number of elements it will iterate:

int nums[5][5];
int all[25];

int a, b;

for (a = 0; a < 5; a++) {
    for (b = 0; b < 5; b++)
        all[((a * 5) + b)] = nums[a][b];
}
Nunchy
  • 948
  • 5
  • 11
1

You mention your question is "how to I fix the code?" I think plenty of people have given you the correct answer. This is your code along with the corrected code.

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int c,i,j,l,k,t;
    printf("Donner le nombres des lignes: ");
    scanf("%d",&l);
    printf("Donner le nombres des colonnes: ");
    scanf("%d",&c);
    int m[l][c];
    t=l*c;
    int v[t];
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("Donner m[%d][%d]: ",i+1,j+1);
            scanf("%d",&m[i][j]);
        }
    }
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("%d\t",m[i][j]);
        }
        printf("\n");
    }
    printf("\n\n\n\n");

    /* corrected code below */
    k = 0;
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            v[k]=m[i][j];
            k++;
        }
    }
    /* corrected code above */

    for(k=0;k<t;k++)
    {
        printf("%d\t",v[k]);
    }
    system("pause");
}
CoryU
  • 163
  • 9
0

This:

for(k=1;k<=t;k++)
   for(i=1;i<=l;i++)
      for(j=1;j<=c;j++)
          v[k]=m[i][j];

does not do what you think. Think about when you first loop through the j part, you will be setting all the 0th element of v the entire time, finally the last value you set will stick (ie, the one in position 1, 1 which happens to be 4). Then you will increment k to 1 and repeat it again, resulting in all 4's. You want this:

 for(i = 0; i < l; i++)
     for(j = 0; j < c; j++)
         v[i*l+j] = m[i][j]; // i*l + j gives you the equivelent position in a 1D vector. 

Make sure your v vector is the right size ie. int v[l*c];. Also remember that in c zero indexing is used.If you really do need 1 based indexing (which you dont ...) then do this:

int k = 1;
  for(i = 1; i <= l; i++)
     for(j = 1; j <= c; j++)
         v[k++]=m[i][j];

But remember that this will make any further operations on this vector Gross. So dont do this ....

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
0

As long as the new array is the correct size, something like the following should work:

k=0;
for(i=0;i<l;i++){
    for(j=0;j<c;j++){
        v[k]=m[i][j];
        k++;
    }
}

Essentially, you are traversing over the matrix (your lines and columns--as you put it) and at the same time increasing the position (k) in the new array where you want that value to be put.

CoryU
  • 163
  • 9
0

If you just want to access the matrix elements as a single dimension array, you could declare an int pointer v:

int m[3][4];
int *v = (int*)m;
// then access for example m[1][1] as v[5]

Or, to actually copy the array, use a double for (as in the other answers), a single for like below

int vv[12];
for(i = 0; i < 12; i++)
    vv[i] = m[i/4][i%4];

or just use memcpy:

memcpy(vv, m, 12*sizeof(int));
nnn
  • 3,980
  • 1
  • 13
  • 17
  • No way! You have no garuntee that `m` is stored in continuous memory! `v[5]` is undefined behaviour~ – Fantastic Mr Fox Nov 17 '15 at 01:03
  • @Ben You're wrong, look for example at http://stackoverflow.com/questions/7784758/c-c-multidimensional-array-internals or http://stackoverflow.com/questions/2565039/how-are-multi-dimensional-arrays-formatted-in-memory – nnn Nov 17 '15 at 01:13