Як очистити масив символів?


86

Мати масив символів, таких як члени char [255]. Як я можу спорожнити його повністю, не використовуючи цикл?

Під "порожнім" я маю на увазі, що якщо в ньому зберігаються деякі значення, то він не повинен. Наприклад, якщо я роблю strcat, то старе значення не повинно залишатися


3
Що ви маєте на увазі "порожній масив"?
pmg

4
members [0] = members [1] = members [2] = members [3] ... = members [255] = 0 немає циклу;)
John La Rooy

18
Отже, ваш "масив" - це особливий тип масиву: це string. Щоб "порожній" рядок, встановіть для першого елемента значення "\ 0":members[0] = '\0';
pmg

Громада, схоже, виступає за мемсет. Але чи це найефективніший спосіб, враховуючи мої вимоги?
Алекс Ксандер,

2
@Alex Xander: "Спільнота" в цьому випадку явно помиляється. Бувають ситуації, що вимагають «memset» (наприклад, знищення даних для запобігання несанкціонованому використанню), але для простого скидання рядка (як у вашому випадку) правильною відповіддю є нуль лише першого елемента.
AnT

Відповіді:


173

використання

загалом

якщо масив знаходиться в області дії, або

якщо у вас є лише значення вказівника, а nMembers - це кількість елементів у масиві.


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


EDIT Для того, щоб використовувати memset , ви повинні включити string.h .


6
+1 - Я б погодився на це, оскільки це гарантує, що всі елементи масиву знаходяться у відомому стані.
ChrisBD

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

1
Хоча memset, ймовірно, не реалізований як рекурсія, він міг би бути - в будь-якому випадку ітерація пристойно прихована від очей, що було нібито вимогою.
Steve Gilham

37

Залежить від того, що ви маєте на увазі під порожнім:


3
Це змінило б лише значення членів [0], а не членів [1] через членів [254]. Чудово, якщо ви отримуєте доступ послідовно ... але в інших випадках не так добре.
Томас Оуенс,

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

3
Не краще рішення. Просто рішення іншої проблеми.
ypnos

4
Немає можливості "спорожнити" абстрактний масив у C. Кожен масив містить щось, навіть якщо це нулі. Поняття "спорожнення масиву" застосовне лише до логічного тлумачення вищого рівня вмісту масиву. Наприклад, вміст масиву може бути інтерпретований як C-рядок. У цьому випадку правильним способом "порожнього" є встановлення для самого першого елемента значення '\ 0'. Саме те, що зробив Фелікс. Я не знаю, які ще інтерпретації може мати на увазі OP, але без конкретизації всі ці спроби з використанням "memset" є лише безглуздими відповідями на безглузде питання.
AnT

1
@tinkertim: Тут немає NULL. І ні, 'strcat' не знає, як обробляти NULL. Він зазнає аварії, якщо ви передасте йому NULL.
AnT

9

Не турбуйтеся, намагаючись обнулити ваш масив char, якщо ви маєте справу з рядками. Нижче наведено простий спосіб роботи з рядками символів.

Копіювати (призначити новий рядок):

Об’єднати (додати рядок):

Порожній рядок:

Просто так.


8

члени char [255] = {0};


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

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

5

РЕДАГУВАТИ: З огляду на останнє редагування запитання, це більше не працюватиме, оскільки не існує нульового закінчення - якщо ви спробували надрукувати масив, ви отримаєте символи, за якими слідує ряд символів, що не читаються людиною. Однак я залишаю цю відповідь тут як спільноту wiki для нащадків.

Це має спрацювати. Відповідно до мови програмування C:

Якщо масив має фіксований розмір, кількість ініціалізаторів не може перевищувати кількість членів масиву; якщо їх менше, інші члени ініціалізуються знаком 0.

Це означає, що кожен елемент масиву матиме значення 0. Я не впевнений, чи саме це ви вважали б "порожнім" чи ні, оскільки 0 є допустимим значенням для char.


Це залежить від того, як ви визначаєте "порожній". Символ зі значенням 0 не є зручним для читання персонажем, і масив символів знаходиться у відомому стані. Я вважав би це порожнім. Він також робить те саме, що і memset (якщо я згадую memset правильно - це вже занадто давно, як я використовував C).
Томас Оуенс,

3

Ви не можете спорожнити масив як такий, він завжди містить однакову кількість даних.

У більшому контексті дані в масиві можуть представляти порожній список елементів, але це має бути визначено на додаток до масиву. Найпоширеніші способи зробити це - вести підрахунок дійсних елементів (див. Відповідь pmg) або для рядків, щоб закінчити їх нульовим символом (відповідь Фелікса). Є також більш складні способи, наприклад, буфер кільця використовує два індекси для позицій, де дані додаються та видаляються.


3

достатньо, враховуючи ваші вимоги.

Однак зверніть увагу, що це не "спорожнення" буфера. Пам'ять все ще виділяється, в ній можуть все ще існувати допустимі значення символів тощо.


1
Можна також записати як * members = 0;
eyalm

Навіть 0є дійсним персонажем. Ми не знаємо, чи membersрозглядають нас як рядок C чи ні.
Sany


2

Я пішов би з


Це насправді має багато сенсу, оскільки OP вимагає операції (спорожнення), яка не є частиною масиву C - отже, в ідеалі він реалізує нову структуру даних, і спосіб сигналізації pmg про пусту структуру досить добре.
Michael Foukarakis

Ні, це справді не має ніякого сенсу.

Кінопіко: Очевидно, ви тоді не розумієте підходу
Крістіан

Kinopiko: прочитайте відповідь starblue, оскільки вона пояснює мої міркування краще, ніж я можу пояснити в коментарі (спасибі starblue)
pmg

Хм, це цікавий підхід, чи буде member_in_use все одно масивом? Чи можу я пізніше зробити a; member_in_use [5] = значення? Це еквівалентно memset (members_in_use, 0, 255); як заявив Стів? Якщо так, то навіщо використовувати одне замість іншого?

1

Під "порожнім масивом", якщо ви маєте на увазі скидання до 0, ви можете використовувати bzero.

Якщо ви хочете заповнити масив яким-небудь іншим символом за замовчуванням, ви можете використовувати функцію memset.


bzero і memset (зазвичай) використовують цикл.
Michael Foukarakis

1

простіше краще - має сенс?

в цьому випадку працює лише учасник [0] = 0. не робіть просте запитання таким складним.


0

Застереження: Зазвичай я не програмую на мові C, тому в моїх прикладах може бути якийсь синтаксис, але я сподіваюся, ідеї, які я намагаюся висловити, є зрозумілими.

Якщо "порожнє" означає "містить порожній рядок", ви можете просто призначити першому елементу масиву нуль, що фактично змусить масив містити рядок empry:

Якщо "спорожнення" означає "звільнення використовуваної пам'яті", спочатку не слід використовувати масив фіксованих символів. Швидше, слід визначити вказівник на char, а потім виконати malloc / free (або присвоєння рядка) відповідно.

Приклад використання лише статичних рядків:


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.