gpt4 book ai didi

c - 在C中正确分隔字符串

转载 作者:太空狗 更新时间:2023-10-29 15:14:28 24 4
gpt4 key购买 nike

我想知道,有什么好的/有效的方法来分隔基本上可以包含任何字符的字符串。例如,我需要连接n个字符串,它们看起来像:

char *str_1 = "foo; for|* 1.234+\"@!`";
char *str_n = "bar; for|* 1.234+%\"@`";

对于最后一个字符串:
char *str_final = "foo; for|* 1.234+\"@!`bar; for|* 1.234+%\"@`"; // split?

我可以使用哪个分隔符来正确分割它?
请注意,可以有两个以上的字符串连接。
我愿意接受建议。
谢谢

最佳答案

因为我的评论越来越长,这里有一个完整的答案:
缓冲区应该将字符串的长度存储在前x个字节中(就像pascal那样)。在该长度之后是字符串数据,它可以包含您喜欢的任何字符。之后,接下来的x字节告诉您下一个字符串的长度。以此类推,直到结束,它由一个空字符串分隔(即最后的x字节声明下一个字符串的长度为零,而您的应用程序将此作为停止查找更多字符串的信号)。
一个好处是,您不需要扫描字符串数据-从第一个字符串的开头查找下一个字符串需要O(1)时间,查找列表中有多少字符串需要O(n)时间,但仍然会非常快(如果O(n)是不可接受的,您可以解决这个问题,但我觉得现在不值得谈这个问题)。
另一个好处是字符串数据可以包含您喜欢的任何字符。这可能是一个con—如果字符串可能包含nul字符,则可以安全地提取它,但必须小心不要将其传递给c string函数(如char *strlen()),该函数将把nul字符视为数据的结尾(可能是,也可能不是)。您将不得不依赖strcat()和指针算法。
问题是x的值(用于存储字符串长度的字节数)。最简单的方法是1,它将绕过所有的endianness和alignment问题,但将字符串限制为255个字符。如果这是一个你可以忍受的限制,很好,但255似乎有点低。
x可以是2个或4个字节,但您需要确保您的数据类型(无符号)至少有那么多字节(memcpy()'sstdint.horuint16_t,or mayuint32_toruint_least16_t)。更好的解决方案是生成uint_least32_t,因为X = sizeof(size_t)类型保证能够存储任何想要存储的字符串的长度。
如果网络可移植性是一个问题,使用size_t将引入对齐和端性。将前x个字节作为X > 1变量读取的最简单方法是将size_t数据转换为char *并取消引用。但是,除非您能保证size_t *数据正确对齐,否则在某些系统上会中断。即使您确实保证了char *数据的对齐,也必须在大多数字符串的末尾浪费几个字节,以确保下一个字符串的长度值对齐。
克服对齐的最简单方法是手动将第一个char *字节转换为sizeof(size_t)值。你必须决定你是希望数据以小尾数还是大尾数存储。大多数计算机本来就很小,但对于手动转换来说,这并不重要——只需选择一台即可。存储在4个字节中的65537(2^16+2),big endian,看起来像size_t;little endian,{ 0, 1, 0, 2 }
一旦你决定了(不要紧,随便选哪一个),你只需把数据的前x个点投射到{ 2, 0, 1, 0 }s,然后再投射到unsigned char,然后用适当的指数做一点移动,把它们放在适当的位置,然后把它们加在一起。在上面的例子中,0乘以2^32,1乘以2^16,0乘以2^8,2乘以2^0(或1),得到0+65536+0+2或65537。如果你在做手动转换的话,大端和小端之间的效率差可能为零,我想再次指出,这个选择完全是任意的。
执行手动转换可以避免对齐问题,并完全绕过对跨系统端点的关注,因此从小端点计算机传输到大端点计算机的数据将被读取。数据从size_t的系统传输到sizeof(size_t) == 4的系统仍然存在潜在问题。如果这是一个问题,您可以a)丢弃sizeof(size_t) == 8并选择一个不变大小,或者b)将发送方的size_t值编码(只需要一个字节)作为数据的第一个字节,并让接收方进行任何必要的调整。选择a)可能更容易,但可能会导致问题(如果您选择的大小太低,无法考虑网络中的旧计算机,并且随着这些计算机的逐步淘汰,您开始没有空间存储您的数据?),所以我更喜欢选择b),因为它可以随您运行的任何系统(16位、32位、64位,甚至将来可能是128位)进行扩展,但您可能不需要这样做。
sizeof(size_t)我把它留给读者来整理我刚刚写的那些乱七八糟的东西。

关于c - 在C中正确分隔字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4093250/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com