如何清空char数组?


83

具有像char成员[255]这样的char数组。如何不使用循环将其完全清空?

char members[255];

“空”的意思是,如果其中存储了一些值,则应该没有。例如,如果我执行strcat,则旧值不应保留

members = "old value";

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

3
你是什​​么意思“空数组”?
09年

4
member [0] = members [1] = members [2] = members [3] ... = members [255] = 0这里没有循环;)
John La Rooy

18
因此,您的“数组”是一种特殊的数组:它是一个string。要“清空”字符串,请将其第一个元素设置为“ \ 0”:members[0] = '\0';
pmg

社区似乎支持memset。但是,这是我所要求的最有效的方法吗?
亚历克斯·桑德

2
@Alex Xander:在这种情况下,“社区”显然是错误的。在某些情况下,需要使用“内存集”(例如清除数据以防止未经授权的使用),但是对于简单的字符串重置(如您的情况),正确的答案是仅将第一个元素清零。
AnT

Answers:


170

使用

  memset(members, 0, 255);

一般来说

  memset(members, 0, sizeof members);

如果数组在范围内,或者

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

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


编辑当然,现在要求已从清除数组的一般任务更改为纯粹重置字符串,这memset是过大的杀伤力,只是将第一个元素清零就足够了(如其他答案中所述)。


编辑为了使用memset,必须包含string.h


6
+1-我会这样做,因为它可以确保所有数组元素都处于已知状态。
ChrisBD,2009年

不过,这违反了不使用循环的要求。
2009年

1
尽管memset可能未实现为递归,但在任何情况下都可以将迭代隐藏在视线之外,这是表面上的要求。
史蒂夫·吉勒姆

36

取决于“空”的含义:

members[0] = '\0';

3
那只会改变members [0]的值,而不是members [1]到members [254]的值。如果您要顺序访问,则可以...但是在其他情况下则不可以。
Thomas Owens

3
在OP编辑之后,看来我的解决方案应该可以满足他的要求,因为strcat()将找到NULL字节并进行相应的处理。
Felix

3
没有更好的解决方案。只是解决另一个问题的方法。
ypnos

4
没有办法在C语言中“清空”抽象数组。每个数组都包含一些东西,即使它为零。“清空数组”的概念仅适用于数组内容的高级逻辑解释。例如,数组的内容可以解释为C字符串。在这种情况下,“空”的正确方法是将第一个元素设置为“ \ 0”。正是费利克斯(Felix)所做的。我不知道OP还会想到什么其他解释,但是如果不做更具体的说明,所有带有“内存集”的尝试都只是对无意义问题的无意义答案。
AnT

1
@tinkertim:这里没有NULL。不,'strcat'不知道如何处理NULL。如果将NULL传递给它,它将崩溃。
AnT

9

如果要处理字符串,请不要试图将char数组归零。下面是使用char字符串的一种简单方法。

复制(分配新字符串):

strcpy(members, "hello");

串联(添加字符串):

strcat(members, " world");

空字符串:

members[0] = 0;

这样简单。


8

char Members [255] = {0};


1
不会,因为他没有指定必须在初始化后完成。特别是在编辑之前,他的第一个示例可能已经理解了这一点,因为这也是清除数组的非常常见的用例。
user44556

我给您+2作为补偿,他给您-1:P:D
stviper

5

编辑:考虑到对问题的最新编辑,它将不再起作用,因为没有null终止-如果您尝试打印数组,则将得到字符,后跟许多非人类可读的字符。但是,我将这个答案留给后代作为社区Wiki。

char members[255] = { 0 };

那应该工作。根据C编程语言:

如果数组的大小固定,则初始化程序的数量不得超过数组成员的数量;如果较少,则将其余成员初始化为0。

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


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

3

您不能像这样清空一个数组,它总是包含相同数量的数据。

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


3
members[0] = 0;

根据您的要求就足够了。

但是请注意,这并不是“清空”缓冲区。内存仍被分配,有效的字符值可能仍然存在,依此类推。


1
也可以写成* members = 0;
eyalm

0是有效字符。我们不知道是否members将其视为C字符串。
三一月


2

我会去

members_in_use = 0;

实际上,这很有意义,因为OP要求的操作(清空)不是C数组的一部分-因此,理想情况下,他将实现一个新的数据结构,而pmg表示该结构的方式为空足够好
Michael Foukarakis,2009年

不,这真的没有任何意义。

Kinopiko:显然您当时不了解这种方法
Christian

Kinopiko:请阅读starblue答案,因为它比注释中的解释更好地解释了我的推理(谢谢starblue)
pmg

嗯,这是一种有趣的方法,members_in_use仍然是数组吗?我以后可以做吗?member_in_use [5] =值?这等效于memset(members_in_use,0,255); 如史蒂夫所说?如果是这样,为什么要使用一个而不是另一个?

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(通常)都使用循环。
2009年

1

越简单越好-有道理吗?

在这种情况下,仅members [0] = 0起作用。不要让一个简单的问题这么复杂。


0

免责声明:我通常不使用C编程,因此示例中可能有语法上的陷阱,但是我希望我尝试表达的思想是清晰的。

如果“ empty”表示“包含一个空字符串”,则只需将第一个数组项分配为零,这将有效地使该数组包含一个empry字符串:

members[0] = 0;

如果“清空”意味着“释放正在使用的内存”,则不应首先使用固定的char数组。相反,您应该定义一个指向char的指针,然后根据需要执行malloc / free(或字符串分配)。

仅使用静态字符串的示例:

char* emptyString="";
char* members;

//Set string value
members = "old value";

//Empty string value
member = emptyString

//Will return just "new"
strcat(members,"new");

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.