2

i'm trying to write a code in C that simply asks the user to enter a number, which will be used to create a matrix (D*D); then to insert characters and then print it.

this is what i wrote:

int d; //matrix size
int i,k; // used for the loops
char **mat; // pointer to a pointer to char

printf("\nenter matrix size\n"); // size of the X*X matrix
scanf("%d",&d);

mat=(char **)malloc(d*sizeof(char *));

for (i=0;i<d;i++)
    mat[i]=(char *)malloc(d*sizeof(char));


printf("enter %d strings with length %d\n",d,d);

for (i=0;i<d;i++)
    for (k=1;k<=d;k++)
    mat[i][k]=getchar();

for (i=0;i<d;i++)
        for (k=0;k<d;k++)
        printf("%c",mat[i][k]);

--if i enter d=3 it freaks out and goes into an endless loop --if i enter 5 for example it gives me only 3 times to enter 4 characters instead of 4.

thanks ppl!

Tom Urkin
  • 61
  • 6

2 Answers2

2

This is going beyond the end of the array, and results in undefined behaviour:

for (i=0;i<d;i++)
    for (k=1;k<=d;k++)       /* this terminating condition */
        mat[i][k]=getchar(); 

I am unsure why k is beginning at 0 as it will skip the first character in the array being read. Change to:;

for (i=0;i<d;i++)
    for (k=0;k<d;k++)
        mat[i][k]=getchar(); 

Note that casting the return value of malloc() is unnecessary (see Do I cast the result of malloc?) and the sizeof(char) is guaranteed to be 1. Always check the result of input operations, scanf(), to ensure that the variable has actually been assigned:

if (1 == scanf("%d",&d))
{
    mat = malloc(d * sizeof(char*));
    if (mat)
    {
        /* ... */
    }
}

Note that the new-line character entered into stdin as a result of the entering of the dimension will remain in stdin after the call to scanf(). This needs to be skipped to prevent from interfering with the subsequent getchar() calls. To skip until the end of the line:

int ch; /* Note that getchar() returns an int, not a char */
while ((ch = getchar()) != '\n' && ch != EOF);

If the user is terminating the strings being entered with a new-line character then you also need to skip it when reading the strings:

for (i=0;i<d;i++)
{
    for (k=0;k<d;k++)
    {
        int ch = getchar();
        if (EOF == ch)
        {
            fprintf(stderr, "Failed to read stdin");
            break;
        }
        mat[i][k]= (char) ch;
    }
    while ((ch = getchar()) != '\n' && ch != EOF);
}
Community
  • 1
  • 1
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • ok so i changed it to: for (i=0;i – Tom Urkin Oct 23 '12 at 14:49
  • For one thing `getchar()` returns the next character, regardless of whether it's a space, or a newline (and if you're on one of those systems that likes to represent a newline as two separate characters, you might get both of them in certain situations). You aren't doing anything to skip whitespace or other non-digit characters, nor are you validating that what you read actually makes sense. – twalberg Oct 23 '12 at 15:01
  • i can't get it to work properly.. is m[0][0] the one on the up most line, first one to the left? because if i try to putchar (mat[0][0]) it does nothing! – Tom Urkin Oct 23 '12 at 17:10
0

I tried in my enviornment using gcc in ubuntu, the only problem i faced of End Line Characted which will comes in to picture when i ask the user for the matrix character value using getchar since when user enters a character, it will press Enter key for its next value to ask as a result \n buffer in stdin and it will become the second input character.As a result of this, when i input 2 , program asking for matrix entry only 2 instead of 4. So for that you can do like:

for (i = 0; i < d i++)
{
   for ( k = 0; k < d; k++)
   {
        getchar();
        mat[i][k] = getchar();
   }

}

please see the for loop of k. it should be like that. In your case, you are accessing the memory which is not present by using k <= d which is not correct