初始化字符数组以保存非空终止字符串。

3

我正在尝试用一个长字符串初始化char数组。但是,我不想让它以NULL结尾。

这样:

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

相对于这个:

来说,

更易读(也更易写)。

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

但前者会以NULL结尾。有没有办法避免字符串字面量上的NULL

这样做的原因是需要在开发期间将字符串紧密地打包到固定大小长度的内存中。


4
为什么你要避免使用“NULL”终止符? - user2508324
1
我们需要更多的信息才能给您一个有用的答案。例如,这个初始化过程只会在程序的生命周期中发生一次吗?性能是否是一个问题?外部问题是什么? - David Schwartz
@DavidSchwartz 它们都是固定长度,且长度相等。 - Baruch
也许你应该使用xxd来生成它们? - Lightness Races in Orbit
1
请将此约束条件添加到问题中。 - Lightness Races in Orbit
显示剩余3条评论
5个回答

4

.

字符串字面值是C字符串,根据定义,它是以空字符结尾的。

要么忽略最后一个字符,重新审视您的需求(为什么关心最后一个字符?!)或…我不知道,也许使用xxd生成对象


1

我会做:

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

看到你所拥有的东西在可读性和功能性之间存在权衡,我认为你可以轻松地应对这一点,因为在“正常”初始化中,你无法避免空终止字符串。

如果我处在你的位置,我会重新考虑我的方法,并使用std::string


1
什么是 length?如果你要执行 strlen,那就是一个 O(n) 的操作。初始化需要一个 O(n) 的操作吗?看起来很重。 - Lightness Races in Orbit
1
是的,我同意。这个需求本身就值得怀疑。 - Lightness Races in Orbit
2
@LightnessRacesinOrbit 你有什么理由认为性能在这里很重要吗?这只是初始化。此外,strlen可以在这里进行优化。你的抱怨听起来像是过早优化——这是让设计比它需要复杂的最糟糕的借口。 - David Schwartz
1
如果他删除了上面那个,我就会删除我的那个和这个。否则,我会保留我的评论以澄清在这里关注性能需要有理由,而我们没有理由。 - David Schwartz
OP正在使用const char[] - Amadeus
显示剩余5条评论

0
不行。如果你想要编写简单的代码,可以将其复制到第二个数组中,但省略最后一个字符。在第一种情况下,您可以使用char指针来节省一些内存。

0

没有办法让字符串文本不以 null 终止。

但实际上,您想要紧密地打包若干个字符串,并且在开发时你知道它们的大小和字符串。

假设:

"第一"

"第二"

"第三"

为了将它们打包,您可以安全地执行以下操作:

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

你只需要保存长度并在需要打印或使用std string时正确重构终止符。这很容易。

作为额外的好处,你还可以节省每个字符串所需的过多指针。


0

如果终止的空字符不适合,它将被省略。由于您的字符串都是固定长度的,所以安排起来并不成问题。例如:

#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');
    }
}

如果我尝试编译这个,会出现“错误:字符数组的初始化字符串太长”的错误。 - Baruch
奇怪。我用C++编译也遇到了这个问题。 - David Schwartz
http://ideone.com/9Wzzgb - Baruch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接