Home > Software engineering >  Can't set second element of an empty string in C
Can't set second element of an empty string in C

Time:10-20

I have this code, which doubles every letter in nabucco:

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

int main(){
        char string1[20] = "nabucco";
        char string2[40];
        int j=-1;
        for(int i=0; i<strlen(string1);i  ){
                j  ;
                string2[j]   = string1[i];
                j  ;
                string2[j] = string1[i];
        }
        printf("string1=\t%s\n",string1);
        printf("string2=\t%s\n",string2);
}

string2 is set to and prints nnaabbuuccccoo.

However, when I try to set j=0; string2 prints (and is presumably set to) nothing.

If j=0 before going into the loop, then j is incremented to 1 in the for loop, which starts off setting the second element of the empty string2. Is there something behind the scenes preventing any element other than the first from being set? I do not understand what is causing this behavior.

CodePudding user response:

The program as posted has undefined behavior since you don't put a null terminator in string2.

If you start with j=0, you never set the value of string2[0] since you increase j before using it, so that position remains indeterminable.

Possible fix:

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

int main(){
        char string1[20] = "nabucco";
        char string2[40];

        size_t j=0;
        for(size_t i=0, len = strlen(string1); i<len; i  ) {
            string2[j  ] = string1[i];  // increase j "after" using the current value
            string2[j  ] = string1[i];
        }
        string2[j] = '\0';                     // add null terminator

        printf("string1=\t%s\n",string1);
        printf("string2=\t%s\n",string2);
}

An alternative could be to initialize string2 when you create it:

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

int main(){
        char string1[20] = "nabucco";
        char string2[40] = {0};           // zero initialized

        for(size_t i=0, j=0, len = strlen(string1); i<len; i  ) {
            string2[j  ] = string1[i];
            string2[j  ] = string1[i];
        }

        printf("string1=\t%s\n",string1);
        printf("string2=\t%s\n",string2);
}

CodePudding user response:

You increment the counter before using it the first time, so if you set j=0 you do j before using it first, which means you start with string2[1].

You can change it like so:

    int j=0;
    for(int i=0; i<strlen(string1);i  ){
            string2[j]   = string1[i];
            j  ;
            string2[j] = string1[i];
            j  ;
    }

CodePudding user response:

When you do this

printf("string2=\t%s\n",string2);

and string2 was set from the second character, this is a sort of undefined behaviour (see also this answer). string2[0] was not initialised, and could contain anything (from sensitive data to something that can't be parsed successfully by other functions - okay, here it is a single character; in other circumstances it could be more than that, if you started with j=20 for example). Which is why undefined behaviour is to be avoided at all costs.

In this case, the quirks of platform, compiler and process made it so the first character is a zero. Since C strings are zero-terminated, and string2 begins with a zero, printf prints nothing. If you printed something like this, where "." is a 0 character (ASCII 0),

 "nnaa.bbuuccoo."

you would get only "nnaa". By the same token, printf'ing ".nnaabbuuccoo" gets you nothing.

If you were to print string2 starting at the second character, you'd get different results:

printf("string2=\t%s\n",string2   1);

CodePudding user response:

After the for loop the character array string2 does not contain a string because you forgot to append it with the terminating zero character '\0'. So this call of printf

printf("string2=\t%s\n",string2);

invokes undefined behavior.

A simplest approach to resolve the problem is to initialize the array in its declaration. For example

char string2[40] = "";

As for this statement

However, when I try to set j=0; string2 prints (and is presumably set to) nothing.

then within the for loop the variable j is at once incremented.

    int j = 0;
    for(int i=0; i<strlen(string1);i  ){
            j  ;
            string2[j]   = string1[i];
            //...

So the first character of the array string2 is not set.

In this case it is better to write the for loop the following way

    size_t j = 0;

    for ( size_t i = 0, n = strlen( string1 ); i < n; i   ){
            string2[j  ] = string1[i];
            string2[j  ] = string1[i];
    }

    string2[j] = '\0';

CodePudding user response:

It is because strings in C are null terminated. So when you set j=0 outside of loop, you skip setting first character which remains null.

  • Related