Как очистить массив символов?


86

Имейте массив символов, например char members [255]. Как я могу полностью его очистить, не используя цикл?

Под «пустым» я подразумеваю, что если в нем были сохранены некоторые значения, то этого не должно быть. Например, если я использую strcat, старое значение не должно оставаться


3
Что значит «пустой массив»?
pmg

4
members [0] = members [1] = members [2] = members [3] ... = members [255] = 0 цикла нет;)
Джон Ла Рой,

18
Итак, ваш «массив» - это особый вид массива: это string. Чтобы «очистить» строку, установите ее первый элемент в '\ 0':members[0] = '\0';
pmg

Сообщество, похоже, поддерживает memset. Но является ли этот способ наиболее эффективным с учетом моих требований?
Alex Xander

2
@Alex Xander: "Сообщество" в данном случае явно ошибается. Есть ситуации, которые требуют 'memset' (например, удаление данных для предотвращения несанкционированного использования), но для простого сброса строки (как в вашем случае) правильный ответ - обнулить только первый элемент.
AnT

Ответы:


173

с помощью

в общем

если массив находится в области видимости, или

если у вас есть только значение указателя, а nMembers - это количество элементов в массиве.


РЕДАКТИРОВАТЬ Конечно, теперь требование изменилось с общей задачи очистки массива на чистый сброс строки, memsetявляется излишним, и достаточно просто обнуления первого элемента (как указано в других ответах).


РЕДАКТИРОВАТЬ Чтобы использовать memset , вы должны включить string.h .


6
+1 - Я бы пошел на это, так как это гарантирует, что все элементы массива находятся в известном состоянии.
ChrisBD,

Однако это противоречит (эпическому) требованию не использовать цикл.
Майкл Фукаракис,

1
Хотя memset, вероятно, не реализован как рекурсия, это могло быть - в любом случае итерация прилично скрыта от глаз, что было мнимым требованием.
Стив Гилхэм,

37

Зависит от того, что вы подразумеваете под словом «пустой»:


3
Это изменит только значение members [0], а не members [1] через members [254]. Хорошо, если вы получаете доступ последовательно ... но не так хорошо в других случаях.
Томас Оуэнс,

3
После редактирования OP кажется, что мое решение должно работать в соответствии с его требованиями, поскольку strcat () найдет нулевой байт и обработает его соответствующим образом.
Феликс

3
Не лучшее решение. Просто решение другой проблемы.
ypnos

4
Невозможно «очистить» абстрактный массив в C. Каждый массив что-то содержит, даже если это нули. Понятие «опустошение массива» применимо только к логической интерпретации содержимого массива более высокого уровня. Например, содержимое массива можно интерпретировать как C-строку. В этом случае правильный способ «опустошить» - это установить для самого первого элемента значение '\ 0'. В точности то, что сделал Феликс. Я не знаю, какие еще интерпретации может иметь в виду ОП, но без уточнения, все эти попытки с «memset» - просто бессмысленные ответы на бессмысленный вопрос.
AnT

1
@tinkertim: Здесь нет NULL. И нет, strcat не умеет обрабатывать NULL. Он выйдет из строя, если вы передадите ему NULL.
AnT

9

Не пытайтесь обнулить массив символов, если вы имеете дело со строками. Ниже приведен простой способ работы со строками символов.

Копировать (назначить новую строку):

Объединить (добавить строку):

Пустой строкой:

Вот так просто.


8

члены типа char [255] = {0};


1
Нет, потому что он не указал, что это нужно делать после инициализации. Особенно это могло быть понято в его первом примере перед редактированием, а также потому, что это также очень распространенный вариант использования для очистки массива.
user44556

Я даю вам +2 в качестве компенсации, которую он дал вам -1: P: D
stviper

5

РЕДАКТИРОВАТЬ: Учитывая последнее изменение вопроса, это больше не будет работать, поскольку нет нулевого завершения - если вы попытаетесь распечатать массив, вы получите свои символы, за которыми следует ряд символов, нечитаемых человеком. Однако я оставляю этот ответ здесь как вики сообщества для потомков.

Это должно сработать. Согласно языку программирования C:

Если массив имеет фиксированный размер, количество инициализаторов не может превышать количество членов массива; если их меньше, оставшиеся элементы инициализируются 0.

Это означает, что каждый элемент массива будет иметь значение 0. Я не уверен, что вы считаете это «пустым» или нет, поскольку 0 - допустимое значение для a char.


Это зависит от того, как вы определяете «пустой». Символ со значением 0 не является понятным для человека символом, а массив символов находится в известном состоянии. Я считаю это пустым. Он также делает то же самое, что и memset (если я правильно помню memset - я слишком давно не использовал C).
Томас Оуэнс,

3

Вы не можете очистить массив как таковой, он всегда содержит одинаковое количество данных.

В более широком контексте данные в массиве могут представлять собой пустой список элементов, но он должен быть определен в дополнение к массиву. Наиболее распространенные способы сделать это - вести подсчет допустимых элементов (см. Ответ pmg) или завершать строки нулевым символом (ответ Феликса). Есть и более сложные способы, например, кольцевой буфер использует два индекса для позиций, в которые данные добавляются и удаляются.


3

достаточно, учитывая ваши требования.

Обратите внимание, однако, что это не «опустошение» буфера. Память по-прежнему выделена, в ней могут существовать допустимые значения символов и т. Д.


1
Также может быть записано как * members = 0;
eyalm

Даже 0действительный персонаж. Мы не знаем members, обрабатываются ли они как строка C или нет.
Sany


2

Я бы пошел с


На самом деле это имеет большой смысл, поскольку OP запрашивает операцию (опорожнение), которая не является частью массива C, поэтому в идеале он должен реализовать новую структуру данных, а способ pmg сигнализировать о структуре пуст достаточно хорошо.
Майкл Фукаракис,

Нет, в этом нет никакого смысла.

Кинопико: Тогда, видимо, вы не понимаете подход,
Кристиан,

Кинопико: прочтите ответ starblue, поскольку он объясняет мои рассуждения лучше, чем я могу объяснить в комментарии (спасибо, starblue)
pmg

Хм, это интересный подход, будет ли members_in_use по-прежнему массивом? Могу я позже сделать; member_in_use [5] = значение? Это эквивалентно memset (members_in_use, 0, 255); как сказал Стив? Если да, то зачем использовать одно вместо другого?

1

Под "очистить массив", если вы имеете в виду сброс до 0, вы можете использовать bzero.

Если вы хотите заполнить массив каким-либо другим символом по умолчанию, вы можете использовать функцию memset.


bzero и memset (обычно) используют цикл.
Майкл Фукаракис,


0

Отказ от ответственности: я обычно не программирую на C, поэтому в моих примерах могут быть какие-то синтаксические ошибки, но я надеюсь, что идеи, которые я пытаюсь выразить, ясны.

Если «очистка» означает «содержащий пустую строку», вы можете просто присвоить первому элементу массива ноль, что фактически заставит массив содержать пустую строку:

Если «очистка» означает «освобождение памяти, которую он использует», вы не должны использовать фиксированный массив символов в первую очередь. Скорее, вы должны определить указатель на char, а затем выполнить malloc / free (или присвоение строки) в зависимости от ситуации.

Пример с использованием только статических строк:


0

Вы можете воспользоваться следующей инструкцией:

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.