1

I have this following program:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char name[50],fname[50],sname[50],lname[50];
    int i,j,k;
    printf("First Name:");
    gets(fname);
    printf("sname:");
    gets(sname);
    printf("lname:");
    gets(lname);

    for(i=0;fname[i]!='\0';i++)
        name[i]=fname[i];
    name[i]=' ';

    for(j=0;sname[j]!='\0';j++)
        name[i+j+1]=sname[j];
    name[i+j+1]=' ';

    for(k=0;lname[k]!='\0';k++)
        name[i+j+k+2]=lname[k];
    name[i+j+k+2]=' ';

    printf("Concatenation is %s",name);
}

I'm confused as to why there is a space assigned in name[i]=' ' and name[i+j+1]=' ' and name[i+j+k+2]=' ' in this program.

If I execute with these, then I'm only getting concatenation, but if I remove them, I'm getting only the string of fname and not a concatenation of all.

Kate Gregory
  • 18,808
  • 8
  • 56
  • 85
Mahi
  • 553
  • 2
  • 7
  • 23
  • 1
    Is there a reason you cannot use `snprintf()` to perform this task? (`snprintf(name, sizeof(name), "%s %s %s", fname, sname, lname); name[sizeof(name) - 1] = '\0';`) – cdhowie Aug 12 '13 at 17:39
  • 8
    Also note that `' '` and `NULL` are two very different things – StephenTG Aug 12 '13 at 17:39
  • 2
    @cdhowie As far as I can understand, it looks like this is code that OP has been given and is trying to understand the behaviour of. – Michelle Aug 12 '13 at 17:43

1 Answers1

8

The key here is that a null character and ' ' (the space character) are not the same. A null character is that '\0' character your for loops are checking for, a.k.a. the end of the string. A space is just a space, inserted between the parts of the name (think about "JamesEarlJones" vs "James Earl Jones" - you definitely want spaces).

It looks like either:

  • by default your arrays are initialized with null characters, which means if you don't assign a value to an element, it'll be '\0' (although this shouldn't be relied upon), or
  • you've got some awfully coincidental placement of null characters going on in the existing memory (there happens to be one after whatever length(s) of first name(s) and full names you've been trying).

If you skip an index when filling the name array (the +1 and +2 in your indices), you're leaving an element as the default/existing value ('\0'). If you don't print a space there, when printing out name, it'll hit a null character after the characters from fname and think that's the end of the string. If you include the lines that add space characters (not the same thing as '\0'), it sees the spaces, prints them, and keeps going.

Michelle
  • 2,830
  • 26
  • 33
  • 3
    Arrays are not implicitly initialized in C. Their values being `'\0'` are accidental, and one should not rely on such semantics. In particular, the `name` array was not initialized with `'\0'` when I compiled and ran the program as it is. I should also point out that the string that ends up in the `name` array is not null-terminated. – Robert Jørgensgaard Engdahl Aug 12 '13 at 18:28
  • @Robert I would expect implicit initialization to be compiler-specific (although I'm having trouble quickly confirming that). I only intended to explain what might cause the behaviour OP is seeing. I edited my answer a bit, but feel free to edit further if you think additional clarification is necessary. – Michelle Aug 12 '13 at 18:41
  • 2
    @Michelle, the definition of the C language is that automatic variables are NOT initialized, as well as `malloc`ed storage. It is dangerous to write code that relies on how one compiler implements that language definition. It makes code unportable, and the next release of the same compiler might change its method of implementation while adhering to the standard. So, in C never rely on an automatic or heap variable being initialized for you. Finally, the C standard does define when and where a variable is initialized by the compiler. – JackCColeman Aug 12 '13 at 23:19
  • @Jack Right, which is why I edited my post to specifically say that one shouldn't rely on uninitialized values. I even went and added bold to it for you :) (And edited again to allow for the possibility that it was all just coincidence.) – Michelle Aug 13 '13 at 00:15
  • The only time variables are guaranteed to be automatically initialised is if they have static storage, e.g. variables declared at file scope, or any variables declared `static`. – dreamlax Aug 13 '13 at 00:45
  • The character constant `\0` is `NUL`, not `null`. – detly Aug 13 '13 at 00:55
  • @Michelle I was responding to your comment "I would expect implicit initialization to be compiler-specific" and that when writing code considerations of compiler-specific features is not an important issue. – JackCColeman Aug 13 '13 at 01:07
  • 2
    `NULL` refers to an [unassigned pointer](http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.11.html). `NUL` is an [ASCII label](http://en.wikipedia.org/wiki/ASCII#ASCII_control_code_chart) for the character constant `\0` (eg. like 'EOT' or 'CR'). `null` isn't really C nomenclature. See [What is the difference between NULL, '\0' and 0](http://stackoverflow.com/questions/1296843/what-is-the-difference-between-null-0-and-0) or [NUL undeclared- first use in this function](http://stackoverflow.com/questions/10546625/nul-undeclared-first-use-in-this-function). – detly Aug 13 '13 at 01:08
  • @Jack Right. Hence the rest of that comment, that I was trying to explain what was happening and how it might be possible, and advised against using it. – Michelle Aug 13 '13 at 01:47
  • @detly "`null` isn't C nomenclature" being the important part there - got it, thanks :) (And edited post to remove use of "`null`".) – Michelle Aug 13 '13 at 01:48
  • 1
    The only reason I'm being pedantic about case is that there *are* similar-looking lower case constants in C++, and it already gets confusing enough :) – detly Aug 13 '13 at 02:07