user1615069
user1615069

Reputation: 633

ANSI C - count the size of the string pointer

Is it possible to create string variables using pointers? So that I don't have to pass its size everytime, like char x[4] = "aaa"?

How can I get the size of such string?

And can I initialize an empty string with a pointer?

Upvotes: 1

Views: 7976

Answers (2)

Chris Hayes
Chris Hayes

Reputation: 12020

Remember that strings in C are ended by the null terminator character, written as \0. If you have a well-formed string stored in your pointer variable, you can therefore determine the length by searching for this character:

char *x = "hello"; // automatically appends a null terminator
int len = 0;
while (x[len] != '\0') {
    len++;
}

If your variables are uninitialized or otherwise not well-formed (e.g., by being NULL) you obviously cannot take this approach; however, most functions are generally written under the assumption that the strings are well-formed, because this leads to faster code.

If you wish to initialize a pointer, you have three options: NULL, a valid address (e.g., char *x = &someCharVar), or a string constant (e.g., char *x = "hello"). Note that if you use a string constant, it is illegal for you to write into that pointer unless you re-assign to it with the address of a non-constant string.

// Get enough space for 24 characters plus null terminator
char *myString = (char*) malloc(25 * sizeof(char));
strcpy(myString, "some text"); // fill the new memory
fgets(myString, 25, stdin); // fill with keyboard input

Note that sizeof(char) is unnecessary here, since a char is always defined to be exactly 1 byte. However, it's a good habit to get into for when you're using other data types, and it helps make your code self-documenting by making your intentions very clear.

Upvotes: 9

John Bode
John Bode

Reputation: 123458

If you're initializing an array of char with a string literal, you don't need to specify the size:

char str[] = "This is a test";

This will create str as a 15-element array of char (the size is taken from the length of the initiliazer, including the 0 terminator) and copy the contents of the string literal to it.

A string literal is an array expression of type "N-element array of char" (const char in C++). Except when it is being used to initialize an array in a declaration (such as above) or is the operand of the sizeof or unary & operators, an expression of type "array of T" will be converted to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.

If you write

const char *str = "This is a test";

the expression "This is a test" is converted from type "15-element array of char" to "pointer to char", and the value of the expression is the address of the first character, which is written to the variable str.

The behavior on attempting to modify the contents of a string literal is undefined; some platforms store string literals in read-only memory, some do not. Some map multiple occurrences of the same string literal to a single instance, others don't. It's best to always treat a string literal as unmodifiable, which is why I declared str as const char * instead of just char *.

To get the length of a string, use strlen:

char str[] = "This is a test"; // or const char *str = "This is a test";
size_t len = strlen(str);      // or strlen("This is a test");

This will return the number of characters in the string up to (but not including) the 0 terminator; strlen("This is a test") will return 14.

To get the size of the buffer containing the string, you would use the sizeof operator:

char str[] = "This is a test";
size_t len = sizeof str;       // or sizeof "This is a test"

Note that this won't give you the size of the buffer if you declared str as a pointer, such as

const char *str = "This is a test";

In that case, sizeof str; only gives you the size of a char *, not the string it points to.

Upvotes: 3

Related Questions