¿Cómo vaciar una matriz de caracteres?

84

Tenga una matriz de caracteres como miembros char [255]. ¿Cómo puedo vaciarlo completamente sin usar un bucle?

char members[255];

Por "vacío" me refiero a que si tenía algunos valores almacenados, entonces no debería. Por ejemplo, si hago strcat, el valor anterior no debería permanecer

members = "old value";

//empty it efficiently
strcat(members,"new"); // should return only new and not "old value new"
Alex Xander
fuente
3
¿Qué quieres decir con "vaciar una matriz"?
pmg
4
miembros [0] = miembros [1] = miembros [2] = miembros [3] ... = miembros [255] = 0 no hay bucle allí;)
John La Rooy
18
Entonces su "matriz" es un tipo especial de matriz: es una string. Para "vaciar" una cadena, establezca su primer elemento en '\ 0':members[0] = '\0';
pmg
La comunidad parece estar a favor de memset. ¿Pero es esa la forma más eficiente dados mis requisitos?
Alex Xander
2
@Alex Xander: "Comunidad" está claramente mal en este caso. Hay situaciones que requieren 'memset' (como borrar datos para evitar el uso no autorizado), pero para el restablecimiento de cadena simple (como en su caso) la respuesta correcta es poner a cero el primer elemento solamente.
el AnT

Respuestas:

171

utilizando

  memset(members, 0, 255);

en general

  memset(members, 0, sizeof members);

si la matriz está dentro del alcance, o

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

si solo tiene el valor del puntero y nMembers es el número de elementos de la matriz.


EDITAR Por supuesto, ahora el requisito ha cambiado de la tarea genérica de borrar una matriz a memsetsimplemente restablecer una cadena, es excesivo y basta con poner a cero el primer elemento (como se indica en otras respuestas).


EDITAR Para usar memset , debe incluir string.h .

Steve Gilham
fuente
6
+1 - Yo optaría por esto, ya que garantiza que todos los elementos de la matriz estén en un estado conocido.
ChrisBD
Sin embargo, va en contra del requisito (épico) de no usar un bucle.
Michael Foukarakis
1
Si bien memset probablemente no se implemente como una recursividad, podría serlo; en cualquier caso, la iteración está decentemente oculta a la vista, que era el requisito ostensible.
Steve Gilham
36

Depende de lo que quieras decir con 'vacío':

members[0] = '\0';
Felix
fuente
3
Eso solo cambiaría el valor de los miembros [0], no de los miembros [1] a los miembros [254]. Bien si accede secuencialmente ... pero no tan bien en otros casos.
Thomas Owens
3
Después de la edición del OP, parece que mi solución debería funcionar para sus requisitos, ya que strcat () encontrará el byte NULL y lo tratará en consecuencia.
Felix
3
No es una mejor solución. Solo una solución a un problema diferente.
ypnos
4
No hay forma de "vaciar" una matriz abstracta en C. Cada matriz contiene algo, incluso si son ceros. La noción de "vaciar una matriz" solo es aplicable a interpretaciones lógicas de nivel superior del contenido de la matriz. Por ejemplo, el contenido de la matriz puede interpretarse como una cadena C. En ese caso, la forma correcta de "vaciar" es establecer el primer elemento en '\ 0'. Exactamente lo que hizo Félix. No sé qué otras interpretaciones podría tener en mente el OP, pero sin hacerlo más específico, todos esos intentos con 'memset' son solo respuestas sin sentido a una pregunta sin sentido.
el AnT
1
@tinkertim: No hay NULL aquí. Y no, 'strcat' no sabe cómo manejar NULL. Se bloqueará si le pasa NULL.
el AnT
9

No se moleste en intentar poner a cero su matriz de caracteres si se trata de cadenas. A continuación se muestra una forma sencilla de trabajar con las cadenas de caracteres.

Copiar (asignar nueva cadena):

strcpy(members, "hello");

Concatenar (agregar la cadena):

strcat(members, " world");

Cuerda vacía:

members[0] = 0;

Tan simple como eso.

Andrejs Cainikovs
fuente
8

miembros char [255] = {0};

user44556
fuente
1
No, porque no especificó que debe hacerse después de la inicialización. Especialmente esto puede haber sido entendido por su primer ejemplo antes de editar y porque también es un caso de uso muy común para borrar una matriz.
user44556
Te doy +2 como compensación que te dio -1: P: D
stviper
5

EDITAR: Dada la edición más reciente de la pregunta, esto ya no funcionará ya que no hay una terminación nula; si intentara imprimir la matriz, obtendría sus caracteres seguidos de varios caracteres no legibles por humanos. Sin embargo, dejo esta respuesta aquí como wiki de la comunidad para la posteridad.

char members[255] = { 0 };

Eso debería funcionar. Según el lenguaje de programación C:

Si la matriz tiene un tamaño fijo, el número de inicializadores no puede exceder el número de miembros de la matriz; si hay menos, los miembros restantes se inicializan con 0.

Esto significa que cada elemento de la matriz tendrá un valor de 0. No estoy seguro si eso es lo que consideraría "vacío" o no, ya que 0 es un valor válido para a char.

Thomas Owens
fuente
Depende de cómo defina "vacío". El carácter con un valor de 0 no es un carácter legible por humanos y la matriz de caracteres se encuentra en un estado conocido. Lo consideraría vacío. También hace exactamente lo mismo que memset (si mi recuerdo de memset es correcto, ha pasado demasiado tiempo desde que usé C).
Thomas Owens
3

No puede vaciar una matriz como tal, siempre contiene la misma cantidad de datos.

En un contexto más amplio, los datos de la matriz pueden representar una lista vacía de elementos, pero eso debe definirse además de la matriz. La forma más común de hacer esto es mantener un recuento de elementos válidos (ver la respuesta por pmg) o cadenas para terminarlos con un carácter cero (la respuesta de Felix). También hay formas más complicadas, por ejemplo, un búfer de anillo usa dos índices para las posiciones donde se agregan y eliminan datos.

estrella azul
fuente
3
members[0] = 0;

es suficiente, dados sus requisitos.

Sin embargo, observe que esto no está "vaciando" el búfer. La memoria todavía está asignada, es posible que todavía existan valores de caracteres válidos en ella, etc.

Michael Foukarakis
fuente
1
También se puede escribir como * miembros = 0;
eyalm
Incluso 0es un personaje válido. No sabemos si membersse tratan como cadena C o no.
Sany
3

Utilizar bzero(array name, no.of bytes to be cleared);

Chibi.Coder
fuente
2

Yo iria con

members_in_use = 0;
pmg
fuente
En realidad, tiene mucho sentido, ya que el OP solicita una operación (vaciado) que no es parte de una matriz C; por lo tanto, idealmente, implementaría una nueva estructura de datos, y la forma de pmg de señalar la estructura está vacía es bastante bueno.
Michael Foukarakis
No, realmente no tiene ningún sentido.
Kinopiko: Aparentemente no entiendes el enfoque entonces
Christian
Kinopiko: lea la respuesta de starblue ya que explica mi razonamiento mejor de lo que puedo explicar en un comentario (gracias starblue)
pmg
Hmm, este es un enfoque interesante, ¿members_in_use seguirá siendo una matriz? ¿Puedo luego hacer una; member_in_use [5] = valor? ¿Es esto equivalente a memset (members_in_use, 0, 255); como dijo Steve? Si es así, ¿por qué usar uno en lugar del otro?
1

Por "vaciar una matriz" si te refieres a restablecer a 0, entonces puedes usar bzero.

#include <strings.h>  
void bzero(void *s, size_t n);  

Si desea llenar la matriz con algún otro carácter predeterminado, puede usar la función memset.

#include <string.h>  
void *memset(void *s, int c, size_t n);  
seguroBadshah
fuente
bzero y memset (normalmente) utilizan un bucle.
Michael Foukarakis
1

más simple es mejor, ¿tiene sentido?

en este caso solo los miembros [0] = 0 funcionan. no hagas una pregunta simple tan complicada.

Prueba
fuente
0

Descargo de responsabilidad: no suelo programar en C, por lo que puede haber algún problema de sintaxis en mis ejemplos, pero espero que las ideas que trato de expresar sean claras.

Si "vaciar" significa "que contiene una cadena vacía", puede simplemente asignar el primer elemento de la matriz a cero, lo que efectivamente hará que la matriz contenga una cadena vacía:

members[0] = 0;

Si "vaciar" significa "liberar la memoria que está usando", no debe usar una matriz de caracteres fija en primer lugar. Más bien, debe definir un puntero a char y luego hacer malloc / free (o asignación de cadena) según corresponda.

Un ejemplo que usa solo cadenas estáticas:

char* emptyString="";
char* members;

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

//Empty string value
member = emptyString

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

Puede utilizar las siguientes instrucciones:

strcpy_s(members, "");
usuario8853435
fuente