1

I do the following for character array intialisation :

  char a[] = "teststring";
  char b[]={'a','a','b','b','a'};

While for the first, if I need to get the string length, I must do strlen(a) ....for the other string I should do sizeof(b)/sizeof(b[0]).

why this difference?

EDIT : (I got this)

char name[10]="StudyTonight";   //valid character array initialization

char name[10]={'L','e','s','s','o','n','s','\0'};    //valid initialization

Remember that when you initialize a character array by listings all its characters separately then you must supply the '\0' character explicitly.

I get that with char b we have to add '\0' to make a proper initialisation.

ANOTHER : Therefore, the array of char elements called myword can be initialized with a null-terminated sequence of characters by either one of these two statements:

char myword[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char myword[] = "Hello"; 
Bhumi Singhal
  • 8,063
  • 10
  • 50
  • 76
  • for any one reading this : I read that if doing strlen ..we shoud do size_t len = strlen(a). ref point in the note: http://stackoverflow.com/questions/2550774/what-is-size-t-in-c. – Bhumi Singhal Sep 19 '15 at 11:38
  • I don't see a difference; `strlen(a)` gives 10, `strlen(b)` gives 5.. – Kenney Sep 19 '15 at 11:38
  • @Kenney : dun think that should be the case. – Bhumi Singhal Sep 19 '15 at 11:39
  • 1
    You can use `sizeof(a)/sizeof(a[0])` for the first case also, but not the other way around because `strlen` relies on the terminating `\0` – robert Sep 19 '15 at 11:41
  • 1
    @Bhumi - true; it depends on what data is defined after `b`... – Kenney Sep 19 '15 at 11:44
  • The `strlen` function scans for a zero char, you even might find one after `{'a','a','b','b','a'};` but this can sometimes take far longer than 5 steps, sometimes totally fail. It's just *undefined behaviour*. – Wolf Sep 19 '15 at 11:54
  • Of course, you shouldn't be using `strlen` _or_ `sizeof` with arrays of anything in C++. – Lightness Races in Orbit Sep 19 '15 at 13:00

4 Answers4

6

A string literal, like "teststring" contains the characters between the double-quotes, plus a terminating char with value zero. So

char a[] = "ab";

has the same effect as;

char a[] = {'a', 'b', '\0'};

strlen() searches for that character with value '\0'. So strlen(a) in this case will return 2.

Conversely, sizeof() gets the actual size of the memory used. Since sizeof(char) is 1, by definition in the standard, this means sizeof(a) give the value of 3 - it counts the 'a', the 'b', and the '\0'.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • 2
    Very good and easy-to-understand description that also includes something about `sizeof`. – Wolf Sep 19 '15 at 11:59
5

a is a C-style string, i.e, null-terminated char array. The initialization is equivalent to:

char a[] = {'t','e','s','t','s','t','r','i','n','g','\0'};

b, however, is not null-terminated, so it's not a C-style string, you can't use functions like std::strlen() because they are only valid for C-style strings.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 1
    if however i do strlen(b) i would get weird answers? or anyway that that could be +- the actual length? – Bhumi Singhal Sep 19 '15 at 11:43
  • 2
    That would be undefined behavior, anything could happen. – Yu Hao Sep 19 '15 at 11:45
  • 4
    You would get undefined behaviour. Anything can happen. In practice, `strlen()` will probably keep searching in memory past the end of the array, until it happens to find a character with value zero. Which, regardless of whether such a character exists or not, means you have a problem. – Peter Sep 19 '15 at 11:47
2

String literals are expanded into char arrays, but also include the terminating zero char. So think the

char a[] = "teststring";

as if you have types this

char a[] = {'t','e','s','t','s','t','r','i','n','g','\0'};

A rule of thumb

Whenever you will use strlen() on a char array, use string literals its for initialization. The strlen function can be thought as a simple scan the terminating zero char (\0) counting the iterations needed.

A word about sizeof

Even if sometimes used with parentheses, sizeof is an operator, an integral part of the C++ language (inherited from C times). In cases like char c[] = "hello";, sizeof(c) will return 6, which is exactly 1 more than strlen(c), and you might be thinking: "lets skip that inefficient scanning for the terminator", but sizeof stops to be such "efficient" as soon as it works on pointers, and arrays can (and will) be used as pointers whenever required. Look at the following example:

#include <iostream>

// naive approach, don't do that
int myarraysize(char s[]) 
{
    return sizeof(s);
}

int main () 
{
    char c[] = "hello";

    std::cout << sizeof(c) << " vs " << myarraysize(c) << std::endl;
    return 0;
}

online demo

Wolf
  • 9,679
  • 7
  • 62
  • 108
2

You can always write

char b[]={'a','a','b','b','a','\0'};

to overcome "the difference".

Also note

 sizeof(b)/sizeof(b[0])

essentially boils down to

 sizeof(b)

since sizeof(char) is always 1. Your formula is used for any other array element types.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190