Home > Mobile >  C with char arrays and indices
C with char arrays and indices

Time:08-04

#include <stdio.h>

int main() {
    char data[8];  // "02/08/10"
    for (int i=0; i<8; i  ) {
        scanf("%c", &data[i]);
    }
    char DD[2];
    for (int i=0; i<2; i  ) {
        DD[i] = data[i];
    }
    char MM[2];
    for (int i=3; i<5; i  ) {
        MM[i-3] = data[i];
    }
    char AA[2];
    for (int i=6; i<8; i  ) {
        AA[i-6] = data[i];
    }
    printf("%s\n", DD);  // "0202/08/10"
    printf("%s\n", MM);  // "080202/08/10"
    printf("%s", AA);  // "10080202/08/10"

    return 0;
}

I wanted DD to be "02", MM "08" and AA "10". What am I doing wrong? Here,
DD --> "0202/08/10"
MM --> "080202/08/10"
AA --> "10080202/08/10"

Why??:?

CodePudding user response:

The %s format specifier in printf expects the string to be NUL-terminated so it knows when to stop outputting characters. But your arrays are not large enough to terminate the data you're filling them with. When printf walks through the string, it runs right off the end of the array and into other memory until it happens to encounter a 0-byte somewhere.

This program therefore has undefined behavior.

Try adding an extra byte to each array and ensure it is zero:

#include <stdio.h>

int main()
{
    char data[8] = "02/08/10";
    char DD[3] = {0};
    char MM[3] = {0};
    char AA[3] = {0};

    for (int i=0; i<2; i  ) DD[i] = data[i];
    for (int i=3; i<5; i  ) MM[i-3] = data[i];
    for (int i=6; i<8; i  ) AA[i-6] = data[i];

    printf("%s\n%s\n%s\n", DD, MM, AA);
}

Alternatively you can tell printf to truncate the string to a specific length by specifying %.2s (where '2' is the number of characters):

#include <stdio.h>

int main()
{
    char data[8] = "02/08/10";
    char DD[2], MM[2], AA[2];

    for (int i=0; i<2; i  ) DD[i] = data[i];
    for (int i=3; i<5; i  ) MM[i-3] = data[i];
    for (int i=6; i<8; i  ) AA[i-6] = data[i];

    printf("%.2s\n%.2s\n%.2s\n", DD, MM, AA);
}

You can also clean up your loops, which are a little messy and prone to mistakes. Look at how much tidier it is with memcpy:

#include <stdio.h>
#include <string.h>

int main()
{
    char data[8] = "02/08/10";
    char DD[2], MM[2], AA[2];

    memcpy(DD, data, 2);
    memcpy(MM, data 3, 2);
    memcpy(AA, data 6, 2);

    printf("%.2s\n%.2s\n%.2s\n", DD, MM, AA);
}

CodePudding user response:

You need add a terminator(\0) to your DD,MM,AA. As printf need to know where to stop.

#include <stdio.h>

int main() {
    char data[8];  // "02/08/10"
    for (int i=0; i<8; i  ) {
        scanf("%c", &data[i]);
    }
    char DD[3];
    for (int i=0; i<2; i  ) {
        DD[i] = data[i];
    }
    DD[2] = '\0';

    char MM[3];
    for (int i=3; i<5; i  ) {
        MM[i-3] = data[i];
    }
    MM[2] = '\0';
    
    char AA[3];
    for (int i=6; i<8; i  ) {
        AA[i-6] = data[i];
    }
    AA[2] = '\0';
    
    printf("%s\n", DD);  // "0202/08/10"
    printf("%s\n", MM);  // "080202/08/10"
    printf("%s", AA);  // "10080202/08/10"
    
    return 0;
}

Output:

02
08
10
  • Related