如何清空一个字符数组?

107

如何在不使用循环的情况下完全清空char数组(如char members[255])?

char members[255];

我所说的"empty"是指如果它之前有存储一些值,则现在应该没有。例如,如果我执行strcat操作,则旧值不应该保留。

members = "old value";

//empty it efficiently
strcat(members,"new"); // should return only new and not "old value new"

3
“empty an array” 的意思是清空一个数组,即将数组中所有的元素都移除。 - pmg
6
成员[0]=成员[1]=成员[2]=成员[3]...=成员[255]=0,没有循环。;) - John La Rooy
22
你的“数组”是一种特殊类型的数组:它是一个“字符串”。要将字符串清空,将其第一个元素设置为'\0':members[0] = '\0'; - pmg
社区似乎支持使用memset。但鉴于我的要求,这是否是最有效的方式? - Alex Xander
@Alex:显然不是这样。虽然无循环的要求看起来有些过头了——你想要避免什么? - Michael Foukarakis
2
@Alex Xander:在这种情况下,“Community”显然是错误的。有些情况需要使用'memset'(例如擦除数据以防止未经授权的使用),但对于简单的字符串重置(如您的情况),正确答案是仅将第一个元素清零。 - AnT stands with Russia
13个回答

207

使用

  memset(members, 0, 255);

总的来说

  memset(members, 0, sizeof members);

如果该数组在作用域内,或者

  memset(members, 0, nMembers * (sizeof members[0]) );

如果您只有指针值,而nMembers是数组中元素的数量。


编辑 当然,现在要求已经从清除数组的通用任务变为纯粹重置字符串,memset过于复杂,只需将第一个元素清零即可(如其他答案中所述)。


编辑 要使用memset,您必须包含string.h


7
+1 - 我会选择这个选项,因为它确保了所有数组元素处于已知状态。 - ChrisBD
这与不使用循环的(史诗级)要求相违背。 - Michael Foukarakis
1
虽然memset可能不是按递归实现的,但它也可以这样做——在任何情况下,迭代都相当隐蔽,这是表面上的要求。 - Steve Gilham

42

取决于你所说的“空”的含义:

members[0] = '\0';

6
这只会改变members[0]的值,而不是members[1]到members[254]的值。如果你按顺序访问,那就没问题......但在其他情况下可能不太好。 - Thomas Owens
4
在 OP 进行编辑后,我的解决方案似乎符合他的要求,因为 strcat() 函数可以找到 NULL 字节并相应地处理它。 - Felix
4
不是更好的解决方案,只是针对不同问题的解决方案。 - ypnos
4
在C语言中,无法"清空"一个抽象数组。每个数组都包含一些东西,即使它们是零。"清空数组"的概念仅适用于对数组内容进行更高级别逻辑解释的情况。例如,数组的内容可能被解释为C字符串。在这种情况下,“清空”数组的正确方法是将第一个元素设置为'\ 0'。就像Felix所做的那样。我不知道OP可能会考虑哪些其他解释,但是如果没有更具体的定义,所有那些使用'memset'的尝试都只是针对无意义问题的无意义答案。 - AnT stands with Russia
1
@tinkertim:这里没有NULL。而且,'strcat'不知道如何处理NULL。如果你把NULL传给它,它会崩溃。 - AnT stands with Russia
显示剩余3条评论

12

如果你正在处理字符串,请不要尝试将char数组清零。下面是一种简单的处理char字符串的方法。

复制(分配新字符串):

strcpy(members, "hello");

连接(将字符串添加在一起):

strcat(members, " world");

空字符串:

members[0] = 0;

就这么简单。


8

char members[255] = {0};


1
不行,因为他没有指定必须在初始化之后完成。特别是在编辑之前的第一个示例中可能已经理解了这一点,因为清除数组也是非常常见的用例。 - user44556
我给你+2作为补偿,因为他给了你-1 :P :D - sfelber

5

编辑:鉴于问题的最新编辑,这种方法将不再适用,因为没有空终止符-如果您尝试打印数组,您将得到您的字符后面跟着一些非人类可读的字符。然而,我将保留这个答案作为社区wiki供后人参考。

char members[255] = { 0 };

这应该可以。根据C编程语言:

如果数组有固定大小,则初始化器的数量不得超过数组成员的数量;如果数量较少,则其余成员将用0进行初始化。

这意味着数组的每个元素都将具有值0。我不确定这是否是您认为的“空”,因为0是char的有效值。


这取决于你如何定义“空”。值为0的字符不是可读字符,而字符数组处于已知状态。我认为那是空的。它也执行与memset相同的操作(如果我对memset的回忆正确的话——自从我使用C以来已经太久了)。 - Thomas Owens

4
使用bzero(数组名称,需要清除的字节数);。它可以用来将一个指定长度的字节区域设置为零。

3
members[0] = 0;

根据您的要求,这已经足够了。

然而请注意,这并没有"清空"缓冲区。内存仍然被分配,有效的字符值可能仍然存在于其中等等。


1
可以写成 *members = 0;。 - eyalm
即使是 0 也是一个有效的字符。我们不知道 members 是否被视为 C 字符串。 - Sany

3

你不能直接清空一个数组,它总是包含相同数量的数据。

在更大的上下文中,数组中的数据可能表示一个空项目列表,但必须除了数组之外进行定义。最常见的方法是保持有效项的计数(参见pmg的答案),或者为字符串添加零字符来终止它们(Felix的答案)。还有更复杂的方法,例如环形缓冲区使用两个索引来指示添加和删除数据的位置。


2
我会选择
members_in_use = 0;

这实际上很有道理,因为OP正在请求执行(清空)的操作并不是C数组的一部分 - 因此,理想情况下,他应该实现一个新的数据结构,并且pmg的信号数据结构为空已经足够好了。 - Michael Foukarakis
不,这真的没有任何意义。 - user181548
Kinopiko:显然你没有理解这种方法。 - Christian
Kinopiko:请阅读starblue的回答,因为他比我在评论中能更好地解释我的推理(谢谢starblue)。 - pmg
嗯,这是一个有趣的方法,members_in_use 仍然会是一个数组吗?我之后可以这样做吗:member_in_use[5] = value? 如果是 Steve 所说的那样,这是否等同于 memset(members_in_use, 0, 255)?如果是,为什么要使用其中一个而不是另一个? - user689383
@BenMezger:不,你误解了我的回答。一个有255个元素的数组将始终有255个元素。没有办法使它具有更少的元素。我的答案使用一个辅助变量来指示其中有多少个元素是“有效的”。 - pmg

1
如果您说“清空数组”是指将其重置为0,则可以使用bzero。
#include <strings.h>  
void bzero(void *s, size_t n);  

如果您想使用其他默认字符填充数组,则可以使用memset函数。
#include <string.h>  
void *memset(void *s, int c, size_t n);  

bzero和memset(通常)都使用循环。 - Michael Foukarakis

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