3

I am trying to initialize a char array with a long string. However, I do not want it to be NULL terminated.

This:

const char s[] = "The actual string is much longer then this...";

is much easier to read (and to write) than this:

const char s[] = {'T', 'h', 'e', ' ', 'a', 'c', 't', 'u', 'a', 'l', ' ', 's', ...};

but the former gets NULL terminated. Is there a way to avoid the NULL on a string literal?

The reason for doing this is that there is the need to pack densely strings in memory of fixed size length known during development.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
Baruch
  • 20,590
  • 28
  • 126
  • 201

5 Answers5

4

No.

A string literal is a C-string which, by definition, is null-terminated.

Either ignore the final character, revisit your requirements (why do you care about a final character?!) or … I dunno, something else. Perhaps generate the objects with xxd?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

I would do:

size_t length = 45;
char s[] = "The actual string is much longer then this..";
s[length - 1] = ".";

See what you have there has a trade-off between readability and functionality and I think that you can get away easily with this, since you can not avoid the NULL terminating string in the "normal" initialization.


If I were in your shoes, I would re-consider my approach and use std::string.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    What is `length`? If you're going to do a `strlen`, that's an `O(n)` operation. An `O(n)` operation for initialization? This looks heavy. – Lightness Races in Orbit Dec 01 '15 at 11:49
  • That rings me a bell @LightnessRacesinOrbit, but if he wants to do that kind of stuff, he better know the length and hard-code it. Otherwise, use a NULL-terminating string. – gsamaras Dec 01 '15 at 11:51
  • 1
    Yes, I agree. The requirement itself is suspect. – Lightness Races in Orbit Dec 01 '15 at 11:51
  • 2
    @LightnessRacesinOrbit Do you have some reason to think performance matters here? This is just initialization. Also, the `strlen` could be optimized out here. Your complaint sounds like premature optimization -- the worst excuse to make a design more complex than it needs to be. – David Schwartz Dec 01 '15 at 12:06
  • @DavidSchwartz Lightness said that because I was worried about it, but we deleted the comments. :) – gsamaras Dec 01 '15 at 12:07
  • 1
    If he deletes the one above, I'll delete my one above and this one. Otherwise, I'm going to keep my comment there to clarify that being concerned about performance here requires a justification and we don't have one. – David Schwartz Dec 01 '15 at 12:09
  • Well @DavidSchwartz the fault here is mine, not one of Lightness. There was a question which used `memcpy()` and I posted a similar comment. So Now Lightness just makes fun of me, but in a good+fair way. – gsamaras Dec 01 '15 at 12:11
  • @DavidSchwartz: I was mostly joking, in response to gsamaras's equivalent comment on another answer. Copy/pasting his conclusion on said issue was the biggest clue :P – Lightness Races in Orbit Dec 01 '15 at 12:14
  • OP was using `const char[]` – Amadeus Dec 01 '15 at 13:33
  • @Amadeus it's the functionality trade-off I mentioned in my answer. ;) – gsamaras Dec 01 '15 at 14:09
0

No. If you want essy to write code, copy to a second array but miss off the last char. You can use a char pointer in the first case to perhaps save some memory

Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
0

The terminating nul will be omitted if it doesn't fit. Since your strings are all fixed length, that's not a problem to arrange. For example:

#include <stdio.h>

char foo[3][4] = { "four", ".by." , "3333" };

int main(void)
{
    for (int i = 0; i < 3; ++i)
    {
         for (int j = 0; j < 4; ++j)
             putchar(foo[i][j]);
         putchar('\n');
    }
}
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0

There is no way to have a string literal not null terminated.

But you actually want to pack a number of strings densely and you know both the sizes and the strings at development time.

Assume:

"First"

"Second"

"Third"

to pack them you can safely do:

char const s[] = "First""Second""Third";

You only need to save lengths and properly reconstruct termination in case you want to print or use std string. That is easy though.

As a bonus you have saved from the excess pointer you would have to store for each and everyone string needed.

g24l
  • 3,055
  • 15
  • 28