Standards in char array declaration in C

53 views Asked by At

What is the best practice on declaring strings / char arrays in C?
I have the below samples and comments.

Code#1
How to properly declare the below?

char message1[] = "abc";  // will add \0 (null character in the end. so message1 is not equal to message2)  
char message2[] = {'a','b','c'}; // tedious to type if you have hundreds of characters to add

Does the recv() socket function in C adds null terminating character at the end?

Code#2
How to compare message4 to message3 if matched partially?

char message3[] = {'a','b','c','e','f'}  
char message4[] = {'a','b'}

Just exploring and new to programming .

Regards

sya

3

There are 3 answers

0
Lundin On BEST ANSWER
  • char message1[] = "abc"; is proper and the normal way. The "" means that a null terminator is added at the end automatically.

  • char message2[] = {'a','b','c'}; is wrong, this is not a C string since it is not null terminated. You could have included a '\0' at the end and then it would become be a correctly declared C string.

  • revc has nothing to do with strings at all, it works on raw data and knows nothing about strings. It deals with given sizes in bytes.

  • Normally you compare strings with strcmp, but in the message3+message4 case, you don't have strings since they were not null terminated. You could instead compare them as raw data with

    memcmp(message3, message4, sizeof(message4)) where it is known that message4 is the smallest one.

0
Nifil On

In C, strings are just characters arrays, they are usually ended by a null terminator allowing functions like strlen, strcmp, strcpy, etc... to work on them.

recv() does not end the buffer with a null terminator, instead it returns the length of the message that was recieved, so if you where to manipulate this buffer as a string, you should use limited functions such as strncmp, strncpy, etc... in which you can explicitly give the size of the array.

char message1[] = "abc"; or const char* message1 = "abc"; are the usual ways of defining a string literals.

So to compare message3 and message4 up the the n-th character you may use strncmp

0
Jon Green On

Initialising char arrays

If you are intending to create a NUL-terminated string, you should always use double-quotes to initialise it, as in your message1[]. This automatically (and implicitly) adds the NUL as the last character in the array.

It is quite rare to initialise a char array to anything other than a NUL-terminated string. If you were using it to store non-string data, you would probably declare it as a int8_t or uint8_t array instead.

However, there are exceptions. If, for example, you were creating a lookup table, indexed by an unsigned integer, to convert a value in the range of 0...15 to its ASCII equivalent in hex, you might use the format of message2[] to make it evident you're never going to use the array as a NUL-terminated string.

That said, most developers would still, for brevity, use a quoted string instead ("0123456789abcdef"), accepting a one-byte waste of space.

recv() semantics

The recv() function acts just like read(), so the same principles apply. It puts exactly and only the number of characters it returns as its return value into the supplied buffer. It does not add a terminal NUL.

Comparing fixed-size arrays

You can't use strlen() to determine the length of message3[] or message4[], as they've been defined with curly brackets, and will not be NUL-terminated. You must assume you will overrun the end of the array!

However, the fact that both their lengths are predefined (char x[] = /*...*/; rather than char *y = /*...*/;) works in your favour. You can use sizeof() on each, take the min() of the two values, and compare only up to that minimum length, thus preventing array overrun.

You should put some thought into whether you consider message3[] "greater than" message4[], given it has the same initial substring but greater length, or whether you consider them equal for your application's purposes.