Search code examples
cfor-loopcharcs50c-strings

why does the variable become 0 suddenly?(c language)


i was practicing basic so i write a code to ask about user name and then i wanted to print user name character by character , then the whole name and the length of it and at the end the even numbers characters of the user name like the 2nd,4th and so on i got two problems first the variable holding name length become zero at the last for cycle my second problem was the even characters as i get odd ones too

i entered the user name : james i expected the out put to be :

j
5
a 
5
m
5
e
5
s
5
hello james , your name has 5 characters
ae
#include <stdio.h>
#include <cs50.h>
#include <string.h>

int main(void)
{
    string name = get_string("whats your name ? ");
    int x = strlen(name);
    char new[4] = "";
    for (int i = 0 ; i < x ; i++)
    {
        printf("%c\n" ,name[i] );
        if ( (i+1) % 2  == 0)
        {
            strcat(new,&name[i]);
        }
            printf("%i\n",x);
    }

    printf("hello %s ,your name has %i characters \n", name,x);
    printf("%s\n",new);
}
whats your name ? james
j
5
a
0
hello james ,your name is 0 characters long
ames

Solution

  • Your entered a string "james" that contains 6 characters including the terminating zero character '\0'.

    whats your name ? james
    

    And you declared a character array that has only 4 elements.

    char new[4] = "";
    

    In this if statement

        if ( (i+1) % 2  == 0)
        {
            strcat(new,&name[i]);
        }
    

    when for example i is equal to 1 the string pointed to by the pointer expression name + 1 is appended to the character array new.

            strcat(new,&name[i]);
    

    This is the following string (represented as a character array) { 'a', 'm', 'e', 's', '\0' }. As it is seen the string contains 5 characters including the terminating zero character '\0'. As a result this call of strcat results in overwritting memory outside the array new that invokes undefined behavior.

    There is no need to use the function strcat because instead of storing only one character in the array new the function tries to append a whole substring.

    You could write for example

    for (int i = 0 ; i < x ; i++)
    {
        printf("%c\n" ,name[i] );
        if ( (i+1) % 2  == 0)
        {
            new[i / 2] = name[i];
        }
            printf("%i\n",x);
    }
    

    Pay attention to that the array new will contain a string because all its elements were initially initialized by zeroes in the array declaration

    char new[4] = "";
    

    On the other hand, using the magic number 4 in the array declaration is unsafe. Instead you could declare for example a variable length array like

    int x = strlen(name);
    char new[x / 2 + 1];
    memset( new, 0, x / 2 + 1 );
    

    In this case your program will work even if the user will enter a more long name.