C multidimensional array pointing problem?

pointer to multidimensional array c
accessing two dimensional array in c using pointers
how to declare two dimensional array using pointers in c++
pointer to multidimensional array c
multidimensional array in c
pointer to 3d array in c
2d array c++
return pointer to 2d array c

Trying to take strings as input and place it in 2d array. Why is this given code showing different behavior. The last for loop "arr[i][j]" is not printing the string.It is not even printing a character also.

Why this code does not work.only this code.Not a new way to write it

This code takes input just fine(or at least the way needed.each row a single string no white space)And when a short string is stored remaining are filled with null after carriage return. When the arr[] is passed in last for loop everything seems fine only when arr[][] is passed ,the problem arises.But again arr[][] is initialized as arr[1][0] then arr[2][0] so should not it work!

#include <stdio.h>
#include <stdbool.h>

int main(void){
    int i,j,m;
    scanf("%d",&m);
    char arr[m][50];
   for(i=0;i<m;i++){
       for(j=0;j<50;j++){   
    printf("please enter a string");
    scanf("%s",&arr[i][j]);
/*j is always 0. arr[i] takes string without space and store ending with null*/
    break;
       }

    }
  //Everything fine upto this,including storing a small continuous string in arr[i](where i<50) and null terminating*/
    for(i=0;i<m;i++){
        for(j=0;j<50;j++){
        printf("%s\n",arr[i][j]);
        break;
    }

}
    }

You program has several issues, like using wrong format specifier:

scanf("%s",&arr[i][j]);

arr[i][j] is a character and you are using %s format specifier. If you want your program should take string as input, you just need to do:

scanf("%s",arr[i]); 

Since, you have given the size 50 characters, put a restriction in scanf() to not to read more than 49 characters (the remain one character space is for null terminating character) like this:

scanf("%49s",arr[i]);
        ^^

Beware with this, it does not discard the remaining input from input stream when the input characters are more than 49 and the remaining characters will be consumed by consecutive scanf() call.

If you want to drop the extra input which wasn't consumed by scanf(), one way of doing it is to read and discard the extra input using a loop, like this:

int c;
while((c = getchar()) != '\n' && c != EOF)
    /* discard the character */;

In case if you have any doubt on how this will discard the extra input, I would suggest first go through getchar().

Putting all these together, you can do:

#include <stdio.h>

int main(void){
    int i,m;
    scanf("%d",&m);
    char arr[m][50];

    for(i=0;i<m;i++){
        printf("please enter a string");
        scanf("%49s",arr[i]);
        int c;
        while((c = getchar()) != '\n' && c != EOF)  // <=== This loop read the extra input characters and discard them
            /* discard the character */;
    }

    for(i=0;i<m;i++){
        printf("%s\n",arr[i]);
    }
    return 0;
}

EDIT

The below edit is because OP updated question and added - Why this code does not work.only this code.Not a new way to write it

Above in my answer, I have already stated that you are using wrong format specifier in the scanf(). In this part of your code:

for(i=0;i<m;i++){
   for(j=0;j<50;j++){   // <====== Nested for loop
printf("please enter a string");
scanf("%s",&arr[i][j]);  
// since the nested loop is supposed to run 50 times, assuming you are trying to read character by character and using %s format specifier
break;
// the nested loop will break in the first iteration itself unconditionally, do you really need nested loop here!
   }

}

Check the inline comments. Hope this might give an idea of the mistakes you are doing.

Seems that you want to read string character by character using scanf(). If this is the case than make sure to take care of null terminating character because, in C, strings are actually one-dimensional array of characters terminated by a null character '\0'. You can do:

#include <stdio.h>

void discard_extra_input() {
        int c;
        while((c = getchar()) != '\n' && c != EOF)
            /* discard the character */;
}

int main(void){
    int i,j,m;

    printf ("Enter number of strings: ");
    scanf("%d",&m);
    discard_extra_input();

    char arr[m][50];
    for(i=0;i<m;i++){
        printf("please enter string number %d: ", i+1);
        for(j=0;j<49;j++){
            scanf("%c",&arr[i][j]);
            if (arr[i][j] == '\n') {
                //need to add null terminating character manually
                arr[i][j] = '\0';
                break;
            }
        }
        if (j==49) {
            // In case where the input from user is more than 50 characters,
            // need to add null terminating character manually.
            arr[i][j] = '\0';

            // discard the extra input when input from user is more than 50 characters.
            discard_extra_input();
        }
    }

    for(i=0;i<m;i++){
        for(j=0;j<50 && arr[i][j]!='\0';j++){
            printf("%c",arr[i][j]);
        }
        printf ("\n");
    }
    return 0;
}

The code is self explanatory except one thing - call to discard_extra_input() function after first input from user scanf("%d",&m);. Reason - Look at the statement:

scanf("%c",&arr[i][j]);

the %c format specifier will consume the leftover newline character '\n' from the input stream due to the ENTER key pressed after first input by the user (number of strings input from user). Hence, in order to discard it, calling discard_extra_input() function. In the other place it has been used to discard the characters when user entered string of size more than 49.

Hope this helps.

Multidimensional Pointer Arithmetic in C/C++, In C/C++, arrays and pointers have similar semantics, except on type information. When a pointer p is pointing to an object of type T, the expression *p is of type interview preparation course with premium videos, theory, practice problems,  In C/C++, arrays and pointers have similar semantics, except on type information. An element at location [2] [1] [2] can be accessed as “ buffer [2] [1] [2] ” or * ( * ( * (buffer + 2) + 1) + 2). When a pointer p is pointing to an object of type T, the expression *p is of type T. For example buffer is of type array of 5 two dimensional arrays.

I know the code. But looking for specific ans. Where the problem lies with the code

The problem is here:

  scanf("%s",&arr[i][j]);

and here:

printf("%s", arr[i][j]);

This is the specific answer you are looking for.

%s won't do any bound checking. It adds the characters starting from the memory location arr + i * m + j to arr + i * m + j + (length of input) + 1 (one extra char for the additional null character that scanf appends). Take a sample input. Assume an arbitrary starting address for arr and do the maths. Also consider any writes beyond the allocated space for arr leads to undefined behavior.

Similarly printf("%s", arr[i][j]); will try to start reading from the address arr[i][j] till it finds a null character. It would usually lead to crash of the code because if your string has ascii characters, the address would be too low to point to any valid user-mapped memory. If your code is working, its mostly because you already have a UB in your scanf.

Get a pen and paper and do some dry runs

4. Pointers and Arrays, Pointers and Arrays An array is a fundamental data structure built into C. A thorough We will also explore problems that can occur when passing and returning arrays. A two-dimensional array is not to be confused with an array of pointers. The simplest form of multidimensional array is the two-dimensional array. A two-dimensional array is, in essence, a list of one-dimensional arrays. To declare a two-dimensional integer array of size [x] [y], you would write something as follows − type arrayName [ x ] [ y ]; Where type can be any valid C data type and arrayName will be a valid

This is a pretty simple problem buddy. You've got the idea right actually, that you need to use 2d array to store strings. Just that the usage is slightly wrong.

First of all let me tell you how 2d arrays need to be used to store in c. In your 2-D array, you've got rows and columns. Say, row represented by i and columns by j, i.e, each row arr[i] contains j elements. So in your context, each row arr[i] contains each string of upto 50 chars. So scanf should be just for arr[i]. And you need to loop with for, m times to accept m strings.

Same applies to printing as well.

Here is the working code:

#include <stdio.h>
#include <stdbool.h>

int main(void){
    int i,j,m;
    printf("\nenter m value:");
    scanf("%d",&m);
    char arr[m][50];
   for(i=0;i<m;i++){ 
    printf("\nplease enter a string no %d: ", (i+1));
    scanf("%s",arr[i]);
    }
    printf("\nthe strings are: \n");
    for(i=0;i<m;i++){
      printf("\n%s\n",arr[i]);
    }
}

And the output in case you want to cross check:

OUTPUT:

enter m value: 3

please enter a string no 1: qwerty

please enter a string no 2: asdfgh

please enter a string no 3: zxcvbn

the strings are:

qwerty

asdfgh

zxcvbn

Pointers to pointers and dynamic multidimensional arrays, a few uses. The most common use is to dynamically allocate an array of pointers: Our dynamic two-dimensional array is a dynamic one-dimensional array of dynamic {0}, {0} // error: excess elements in array initializer. };. A float * points to a float, which might be the first value in a single-dimensional float array. But it does not point to any sub-array, as you would need for a multidimensional array. 2x2 and 3x3 are both 2D, so both could be a float **. Really, though, you'd be much better off creating (or finding) and using a dedicated Matrix class.

Two dimensional (2D) arrays in C programming with example, How do I assign a 2-D array to a pointer ? I am getting error. Reply. raztek says. September 1, 2015 at 10:  C Programming: Multidimensional Arrays (Solved Problem) Topics discussed: 1) C program to read a 5x5 array of integers and then print the row sum and column sum.

Two-Dimensional Arrays \ Processing.org, A two-dimensional array is really nothing more than an array of arrays (a We might write the two-dimensional array out as follows to illustrate this point: Write a C program to input and print elements of a two dimensional array using pointers and functions. To access a two dimensional array using pointer, let us recall basics from one dimensional array. Since it is just an array of one dimensional array. Suppose I have a pointer array_ptr pointing at base address of one dimensional array.

C Multidimensional Arrays (2d and 3d Array), In this tutorial, you will learn to work with multidimensional arrays (two-​dimensional and three-dimensional arrays) in C programming with the help of examples. In C programming, you can create an array of arrays. These arrays are known as multidimensional arrays. Here, x is a two-dimensional (2d) array. The array can hold 12 elements. You can think the array as a table with 3 rows and each row has 4 columns. Here, the array y can hold 24 elements. You can initialize a three-dimensional array in a

Comments
  • 1. Why do you have a nested for loop and an unconditional break after that? 2. How many strings do you need to store? 3. to printf with %s you need to give the address of the array of characters, which you are not giving. 4. You do not have proper indentation.
  • I'd say the culprit is scanf("%s",&arr[i][j]);, that address, is not fit to store anything more than an empty-string.
  • @SouravGhosh but still it stores in strings. The problem is it is unable to print with that line of code.
  • Variable length array?
  • char arr[m][50]; so arr[i][j] is type char, not char*. You are using scanf("%s",&arr[i][j]); which is attempting to store a string at the address of arr[i][j] (which is fine by happy-accident when j = 0; but then begins overwriting your prior string (offset by 1-char as j increments)). Further char arr[m][50]; declares a VLA of m rows with 50 characters per-row. As j increases, the number of characters available for storage in the row decreases by the same amount.
  • A good answer; some comments about why c needs to be an int, and why it is necessary to test for EOF when clearing the input stream would make it even better.
  • @DavidBowling Thanks, added reference link for getchars(). Let the OP give some effort and try to understand it by himself. Also, removed unused variable j from the code.
  • @givil check the EDIT.
  • "scanf("%s",&arr[i][j]); // trying to read a character using %s format specifier." Apparently the small input string overwrites in arr[i] location (as it has upto 50 spaces). But then after carriage return all the rest (50-string length )is filled with null. and then the process repeats m times with different arr[i] values actually storing the strings in arr[i](where 0<i<50) and ending each string with null.
  • @givil &arr[i][j] -> &(*(arr+i))[j] -> &(*(*(arr+i))+j). Now since you are breaking the nested loop in first iteration in which value of j is 0. Hence, the expression for j=0 will be - &(*(*(arr+i))+0) -> &(*(*(arr+i))) -> (*(arr+i)) -> arr[i]. That means this statement - scanf("%s",&arr[i][j]); is equivalent to scanf("%s",arr[i]); only when j=0. Having the nested loop supposed to run for 50 times and breaking it in first iteration doesn't make any sense but making the code obfuscated.
  • "%s won't do any bound checking. It adds the characters starting from the memory location arr + i * m + j to arr + i * m + j + (length of input) + 1 (one extra char for the additional null character that scanf appends). " Will it not stop at null character if found before array length?
  • Nope. scanf won't read the array. It will just write to it blindly.