0

Edit: After asking this question I was informed about the question How to initialize a char array without the null terminator? which is almost identical. (I'm building a network packet as well.)

I'll keep this question open anyway, because I'm just assigning and not initializing.


I have a fixed size array that I would like to assign a fixed text to:

char text[16]; text = "0123456789abcdef"; 

Of course this doesn't work because the right hand side contains the null terminator.

error: incompatible types in assignment of 'const char [17]' to 'char [16]' 

The text is human-readable, so I would prefer to keep it in one piece, i.e. not write {'0', '1', ...}.

Can I make the assignment work somehow?

By the way, I only have a few hundred bytes of RAM, so preferably (but second to the human-readability requirement) the solution shouldn't use twice the RAM for a temporary copy or something like that.

10
  • 1
    In C, strcpy(text, "0123456789abcde"); /* text has space for 15 "real" characters and the zero terminator */ Note that strcpy(text, "0123456789abcdef"); is an error! Commented Jul 14, 2020 at 11:36
  • 4
    Are you asking about C or C++? There is a difference. Commented Jul 14, 2020 at 11:37
  • 2
    char text[] = "0123456789abcdef"; Commented Jul 14, 2020 at 11:38
  • 4
    So the question is about how to store 17 bytes in 16 byte array? Commented Jul 14, 2020 at 11:41
  • 2
    @AndreKR Then see How to initialize a char array without the null terminator? TLDR: char text[16] = "0123456789abcdef"; (note that won't work in C++) Commented Jul 14, 2020 at 12:17

2 Answers 2

2

If you write in C:

char text[16]; strncpy(text, "0123456789abcdef", sizeof(text)); 

Note that text will not have the null-terminator and won't be compatible with the standard C functions like strlen. If the text if human-readable, I recommend to include the terminator. It is only one character but it will make your life much easier.

Example:

char text[17]; strncpy(text, "0123456789abcdef", sizeof(text)); 
Sign up to request clarification or add additional context in comments.

Comments

0

First of all, in case you have any misunderstanding -- "0123456789abcdef" is a string literal. Its type is const char [17], not const char [16], because this string literal has a null terminator \0 in the end.

Then I assume you do mean assignment not initialization. They are different.

I can think of multiple ways to do the assignment. You may choose based on your needs.

#include <cstddef> #include <cstring> #include <iostream> #include <string> #include <string_view> using std::size_t; template<size_t N> void print(const char (&a)[N]) { for (size_t i = 0; i != N; ++i) putchar(a[i]); putchar('\n'); } void foo1() { char text[16]; std::memcpy(text, "0123456789abcdef", sizeof text); print(text); } void foo2() { char text[16]; std::string("0123456789abcdef").copy(text, sizeof text); print(text); } void foo3() { char text[16]; std::string_view("0123456789abcdef").copy(text, sizeof text); print(text); } // programmer needs to make sure access with src is valid template<size_t N> void assign(char (& dest)[N], const char * src) { for (size_t i = 0; i != N; ++i) dest[i] = *src++; } void foo4() { char text[16]; assign(text, "0123456789abcdef"); print(text); } int main() { foo1(); // 0123456789abcdef foo2(); // 0123456789abcdef foo3(); // 0123456789abcdef foo4(); // 0123456789abcdef return 0; } 

Some remarks:

  • std::memcpy is the traditional memory copy way from C
  • std::string_view is a light-weight view on a string, introduced in C++17
  • Or you may write your own function like assign() -- with a template you can tell the size of an array at compile time. Depending on your needs, you may decide whether or not to implement bounds checking.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.