0

I have this code:

#include <stdio.h>

int main(void) {
    char p[5][5];
    int i,j;

    for(i=1;i<=1;i++){
        for(j=1;j<=2;j++) {
            printf("\nInput Product code %d of day %d: ", j,i);
            scanf("%s", &p[i][j]);
        }
    }

    for(i=1;i<=1;i++){
        for(j=1;j<=2;j++) {
            printf("\n\tProduct code %s day %d", &p[i][j],i);
        }
    }

}

This code outputs:

Input Product code 1 of day 1: hello

Input Product code 2 of day 1: hi

  Product code hhi day 1

Product code hi day 1

Does anyone know why hello and hi are interconnecting instead of printing hello in the first one?

I have researched a lot on strings but none seem to work better than this one.

2
  • for(i=1;i<=1;i++) seems a wee bit pointless to me... Commented May 14, 2013 at 16:23
  • yep..making sure it works the first time, wouldn’t want to waste any of my precious time Commented May 14, 2013 at 18:46

3 Answers 3

2

p[][] is not a double array of strings but a double array of chars. It has 5 rows and 5 columns like this:

p[row][column] = 

 Row| Column ->         |
  v | 0 | 1 | 2 | 3 | 4 |
| 0 |   |   |   |   |   |
| 1 |   |   |   |   |   |
| 2 |   |   |   |   |   |
| 3 |   |   |   |   |   |
| 4 |   |   |   |   |   |

The first scanf() is called when i = 1, j = 1 and copies the string "hello" leaving p[][] like this ('\0' is the NUL character that terminates strings):

    | 0 | 1 | 2 | 3 | 4 |
| 0 |   |   |   |   |   |
| 1 |   | H | e | l | l |
| 2 | o |\0 |   |   |   |
| 3 |   |   |   |   |   |
| 4 |   |   |   |   |   |

The next time it is called, i = 1, j = 2:

    | 0 | 1 | 2 | 3 | 4 |
| 0 |   |   |   |   |   |
| 1 |   | H | h | i |\0 |
| 2 | o |\0 |   |   |   |
| 3 |   |   |   |   |   |
| 4 |   |   |   |   |   |

One way you could write this:

#include <stdio.h>
#define MAX_CODE_LEN   80 /* or something */

int main(void) 
{
    char *code[5][5] = {0},
         currentCode[MAX_CODE_LEN] = {0};
    int day = 0,
        codeNum = 0;

    /* start loops at 0 */
    for ( day = 0; day < 5; day++ ) {

        for ( codeNum = 0; codeNum < 5; codeNum++ ) {
            int len = 0;

            printf("\nInput Product code %d of day %d: ", codeNum, day);
            scanf("%s", currentCode);

            /* len doesn't include NUL but malloc needs it */
            len = strlen(currentCode);

            /* yoda style so compiler catches assignment instead of equality */
            if ( 0 == len ) {
                /* if the user didn't enter a code move onto the next day */
                code[day][codeNum] = NULL;
                break;
            }
            len = len >= MAX_CODE_LEN? MAX_CODE_LEN - 1: len;
            code[day][codeNum] = malloc(len * sizeof(char) + 1);
            strcpy(code[day][codeNum], currentCode);
        }
    }

    for ( day = 0; day < 5; day++ ) {

        for ( codeNum = 0; codeNum < 5; codeNum++ ) {

            if ( NULL == code[day][codeNum] ) {
                /* no more codes for today */
                break;
            }
            printf("\n\tProduct code %s day %d", code[day][codeNum], day);
        }
    }

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

0
char p[5][5];

this is a matrix of charachters and not matrix of strings

and with your scanf(), you want to put for each element in the matrix a string. And this is impossible.

You have to use one of the following definition:

1)

char p[5][5][MAX_SIZE_OF_INPUT_STRINGS];

and the scanf should be

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

2)

char *p[5][5];

and the scanf should be

scanf("%ms", p[i][j]);

p[i][j] here is pointed to a memory allocated dynamically by scanf() and you have to free it with free(p[i][j]) when the p[i][j] become useless in your program

1 Comment

I think this is off-target. There's no need to add a third dimension to the array to make the code work.
0

The reason is because strings are just arrays of chars(terminated by \0 or null. Right now, you're indexing chars, and scanf is just taking the char reference you pass it, and filling the rest of the structure with it until it's done filling with the string.

what you're doing is setting p to

* * * * *
* h e l l
o\0 * * *
* * * * *
* * * * *

and then

* * * * *
* h h i\0
o\0 * * *
* * * * *
* * * * *

If I were you, I'd populate closer to something like this

char p[5][6];
int i,j;


for(i=0;i<2;i++)
{

    printf("\nInput Product code of day %d: ", i);
    scanf("%s", &p[i]);
}

for(i=0;i<2;i++)
{
    printf("%s\n", &p[i]);
}

2 Comments

It's not quite that simple: p[1][0] has no specific value; p[1][1] contains the h of hello; p[1][2] contains the h of hi, etc. The entry of hello overruns the end of the sub-array p[1], writing to p[2][0] and p[2][1]. However, the suggested fix, including the extra space for the null, is about right.
@JonathanLeffler didn't take into account the indexing at 1 on the j variable

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.