What is Declaring C String Variables- Embedded C Programming Course Online

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

Free C Programming Course · Chapter 9 · Lecture 4 of 7

Declaring C String Variables

Declare, initialise and size char arrays that hold text, and copy into them without overflowing.

9
Chapter: Strings
4/7
Lecture in this chapter
Free
Always, for every student

What You Will Learn

  • How to declare a C string variable and size it correctly
  • Three ways to initialise a string variable and what bytes each produces
  • What happens to the unused part of a larger array
  • Why sizeof and strlen differ and when to use each
  • How to copy text into a fixed buffer without overflowing it
  • How to catch sizing mistakes at compile time with _Static_assert

Prerequisites

  • Lecture 1: C strings and the NUL terminator
  • Lecture 3: the rule that literals are read-only

Reading text is only half of the story. Real programs need C string variables that they can fill, edit and print. This lecture of the free C programming course shows how to declare them, how big to make them, and how to avoid the overflow bugs that give C its reputation. It is an essential topic in any free embedded C course because firmware buffers are small and fixed.

Declaring C String Variables

A C string variable is simply a char array with enough room for the text and the terminator. There is no separate declaration syntax for it. You pick the capacity yourself, and from then on you are responsible for never writing past it.

DeclarationArray sizeContents (after NUL)
char a[] = {'N', 'V', 'M', '\0'};4N V M NUL
char b[] = "NVM";4N V M NUL
char c[8] = "NVM";8N V M NUL then four zero bytes
char d[] = "";1NUL
char e[8]; (local)8garbage until you write to it

The first two forms are identical. The second is easier to read and removes the chance of forgetting the terminator, because the compiler adds it. Leaving the brackets empty makes the compiler count the characters for you, so the size can never be off by one.

Memory of char c[8] = NVM

Index01234567
ValueNVM\0\0\0\0\0
Hex4E564D0000000000
Part of the string?yesyesyesterminatorunusedunusedunusedunused

Only the bytes up to the first zero belong to the string. The remaining bytes are spare capacity. Text can grow into them later, but only while a terminator is kept after the last character.

Run It: Sizes, Bytes and a Safe Copy

Save the following as string_vars.c. It builds four variables, dumps their bytes, uses a compile-time check, and copies an oversized text into a small buffer safely.

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

static void dump(const char *label, const char *buf, size_t n)
{
    printf("%-9s:", label);
    for (size_t i = 0; i < n; i++)
        printf(" %02X", (unsigned char)buf[i]);
    printf("   (sizeof %zu, strlen %zu)\n", n, strlen(buf));
}

int main(void)
{
    char a[] = {'N', 'V', 'M', '\0'};
    char b[] = "NVM";
    char c[8] = "NVM";
    char d[] = "";

    _Static_assert(sizeof(b) == 4, "NVM needs 3 chars + 1 NUL");

    dump("a", a, sizeof a);
    dump("b", b, sizeof b);
    dump("c[8]", c, sizeof c);
    dump("d", d, sizeof d);

    /* Safe copy into a fixed buffer: snprintf always terminates */
    char name[8];
    snprintf(name, sizeof name, "%s", "TOOLONGNAME");
    printf("name = [%s], strlen = %zu, sizeof = %zu\n",
           name, strlen(name), sizeof name);
    return 0;
}
gcc -std=c17 -Wall -Wextra -o string_vars string_vars.c
./string_vars

Expected output:

a        : 4E 56 4D 00   (sizeof 4, strlen 3)
b        : 4E 56 4D 00   (sizeof 4, strlen 3)
c[8]     : 4E 56 4D 00 00 00 00 00   (sizeof 8, strlen 3)
d        : 00   (sizeof 1, strlen 0)
name = [TOOLONG], strlen = 7, sizeof = 8

A friendly compiler warning

On GCC 13 this build prints a -Wformat-truncation warning for the snprintf line. That is the compiler noticing, at compile time, that the literal is longer than the buffer. We keep the line on purpose to show the safe behaviour, which is truncation, not overflow.

What to notice

  • d is a valid empty string: size 1, length 0, one zero byte.
  • c has size 8 but length 3. The capacity and the text length are different numbers.
  • _Static_assert verified at compile time that b has exactly 4 bytes. If someone edits the text, the build fails instead of the firmware.
  • snprintf stored seven characters and the terminator and silently dropped the rest, so the buffer was never overrun.

Sizing C String Variables Correctly

The capacity rule is: longest possible text plus one. If a device name can be at most 7 characters, the buffer needs 8 bytes. Define that number once, for example as a macro, and use sizeof on the array whenever you pass a limit to a function.

Decide longest text → Add 1 for the NUL → Declare the array → Pass sizeof to copy functions → Check for truncation

Use sizeof only on the array itself, not on a pointer to it. Once an array is passed to a function it becomes a pointer, and sizeof inside the function reports the size of the pointer, not of the buffer. Always pass the capacity as a separate argument.

Real-World Uses of String Variables

Use 1

Receive buffers

A UART interrupt fills a char rx[32] one byte at a time and appends a terminator when a newline arrives.

Use 2

Formatted output

snprintf(buf, sizeof buf, "T=%d", temp) builds a display line without overflow.

Use 3

Device identifiers

Serial numbers and names are stored in fixed-size arrays inside a configuration structure.

Common Mistakes With String Variables

MistakeConsequenceFix
Array exactly as long as the textNo room for the terminatorCapacity = length + 1
Using = to copy a string into an arrayCompile error; arrays are not assignableUse snprintf or memcpy
Using strcpy with unknown lengthBuffer overflowUse a bounded copy and check the result
Reading an uninitialised local arrayGarbage text, undefined behaviourInitialise with = "" or = {0}
sizeof on a function parameterReturns pointer sizePass the capacity explicitly

Best Practices, Performance and Security

  • Initialise every string variable, even to an empty string, so it is always a valid string.
  • Prefer snprintf(buf, sizeof buf, "%s", src) for bounded copies; it always terminates.
  • Performance: char c[8] = "NVM" zero-fills the tail on every initialisation. In hot paths, initialise once or use a static buffer.
  • Security: a stack buffer overflow is one of the oldest exploitable bugs. Fixed capacity plus bounded copies closes the door.

Summary and Key Takeaways

  • A string variable is a char array sized for the text plus the terminator.
  • Leave the brackets empty to let the compiler count the size from the literal.
  • Unused bytes in a larger array are zero-filled when you initialise it.
  • sizeof is capacity; strlen is current text length.
  • Copy with bounded functions, and verify sizes with _Static_assert where possible.

You can now create and size writable strings. In the next lecture you will learn to walk through a string, one character at a time, with both an index and a pointer, and to compute a string’s length by hand.

Frequently Asked Questions

How do I declare a string variable in C?

Declare a char array big enough for the longest text plus one byte for the terminator, for example char name[16];, or let the compiler size it from an initialiser: char name[] = "NVM";.

What is the difference between sizeof and strlen for a string variable?

sizeof gives the total capacity of the array in bytes, known at compile time. strlen counts the characters before the first zero byte and is computed at run time. For char c[8] = "NVM" they return 8 and 3.

What happens to the unused bytes when I write char c[8] = “NVM”?

When an array is initialised with fewer values than its size, the remaining elements are set to zero. That is why the output in this lecture shows four 00 bytes after the terminator.

Can I assign a string to an array with = after the declaration?

No. Arrays cannot be assigned. After the declaration you must copy characters with strcpy, memcpy or, preferably, snprintf, which also guarantees a terminator.

What if the text is longer than the array?

Initialising an array with a longer literal is a compile error or warning. Copying longer text into it at run time overflows the buffer and is undefined behaviour. Use a bounded function such as snprintf and check for truncation.

Is an empty string the same as an unset string?

An empty string "" has one byte, the terminator, and is a valid string of length zero. An uninitialised local char array holds garbage and is not a valid string until you write a terminator into it.

Topics Covered in This Lecture

C string variableschar arraysizeof vs strlensnprintf_Static_assertembedded C programmingfree embedded C course

Keep Going With the Free C Programming Course

EmbeddedPathashala teaches C from the first printf to embedded-ready pointers and strings, completely free. Next: walking through a string with indexes and pointers.

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *