初始化char数组以保存非空终止字符串[重复]
Posted
技术标签:
【中文标题】初始化char数组以保存非空终止字符串[重复]【英文标题】:Initialize char array to hold non-null-terminated string [duplicate] 【发布时间】:2015-12-01 11:42:16 【问题描述】:我正在尝试使用长字符串初始化 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
?
这样做的原因是需要在开发期间已知的固定大小长度的内存中密集地打包字符串。
【问题讨论】:
为什么要避免使用NULL
-terminator?
我们需要更多信息才能为您提供有用的答案。例如,这种初始化是否只会在程序的生命周期中发生一次?性能有问题吗?外部问题是什么?
它实际上是一个字符串数组,为了各种快速索引目的,我需要将它们紧紧地打包到内存中(字符串之间没有NULL
)
索引数组的代码如何知道字符串在哪里结束?
请将此约束添加到问题中。
【参考方案1】:
否。
字符串字面量是一个 C 字符串,根据定义,它是以 null 结尾的。
要么忽略最终角色,重新审视你的要求(你为什么关心最终角色?!)或者......我不知道,别的。也许generate the objects with xxd
?
【讨论】:
【参考方案2】:我愿意:
size_t length = 45;
char s[] = "The actual string is much longer then this..";
s[length - 1] = ".";
看看你有什么在可读性和功能之间进行权衡,我认为你可以轻松摆脱这一点,因为你可以不避免“正常”中的 NULL 终止字符串初始化。
如果我处于你的位置,我会重新考虑我的方法并使用std::string。
【讨论】:
什么是length
?如果您要执行strlen
,那就是O(n)
操作。用于初始化的O(n)
操作?这看起来很重。
这给我敲响了@LightnessRacesinOrbit,但如果他想做那种事情,他最好知道长度并对其进行硬编码。否则,使用以 NULL 结尾的字符串。
是的,我同意。需求本身是可疑的。
@LightnessRacesinOrbit 你有理由认为性能在这里很重要吗?这只是初始化。此外,strlen
可以在这里进行优化。你的抱怨听起来像是过早的优化——让设计变得比它需要的更复杂的最糟糕的借口。
如果他删了上面那个,我就删我上面那个和这个。否则,我将保留我的评论,以澄清在这里关注性能需要一个理由,而我们没有理由。【参考方案3】:
如果不合适,终止的 nul 将被省略。由于您的字符串都是固定长度的,因此安排起来不是问题。例如:
#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');
【讨论】:
如果我尝试编译这个我得到error: initializer-string for array of chars is too long
很奇怪。编译成C++,我也明白了。
ideone.com/9Wzzgb【参考方案4】:
没有。如果您想用 essy 编写代码,请复制到第二个数组但错过最后一个字符。您可以在第一种情况下使用 char 指针来节省一些内存
【讨论】:
【参考方案5】:没有办法让字符串文字不以 null 结尾。
但您实际上想要密集地打包多个字符串,并且您在开发时就知道字符串的大小和字符串。
假设:
“第一”
“第二”
“第三”
您可以安全地打包它们:
char const s[] = "First""Second""Third";
如果您想打印或使用标准字符串,您只需要保存长度并正确重建终止。不过这很容易。
作为奖励,您从多余的指针中节省下来,您必须为每个需要的字符串存储。
【讨论】:
以上是关于初始化char数组以保存非空终止字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章