Jak opróżnić tablicę znaków?


86

Miej tablicę znaków, takich jak członkowie znaków [255]. Jak mogę go całkowicie opróżnić bez używania pętli?

Przez „pusty” rozumiem, że gdyby zawierał jakieś wartości, to nie powinien. Na przykład, jeśli zrobię strcat, stara wartość nie powinna pozostać


3
Co masz na myśli mówiąc „opróżnij tablicę”?
pmg

4
członkowie [0] = członkowie [1] = członkowie [2] = członkowie [3] ... = członkowie [255] = 0 brak pętli;)
John La Rooy

18
Więc twoja "tablica" jest specjalnym rodzajem tablicy: jest to string. Aby „opróżnić” ciąg, ustaw jego pierwszy element na „\ 0”:members[0] = '\0';
pmg

Wydaje się, że społeczność popiera memset. Ale czy jest to najbardziej efektywny sposób, biorąc pod uwagę moje wymagania?
Alex Xander

2
@Alex Xander: „Społeczność” jest w tym przypadku ewidentnie błędna. Są sytuacje, które wymagają „memset” (np. Wymazywanie danych, aby zapobiec nieautoryzowanemu użyciu), ale w przypadku prostego resetowania ciągu znaków (jak w twoim przypadku) poprawną odpowiedzią jest wyzerowanie tylko pierwszego elementu.
AnT

Odpowiedzi:


173

za pomocą

ogólnie

jeśli tablica jest w zakresie, lub

jeśli masz tylko wartość wskaźnika, a nMembers to liczba elementów w tablicy.


EDYCJA Oczywiście, teraz wymaganie zmieniło się z ogólnego zadania czyszczenia tablicy na czyste resetowanie ciągu, memsetjest przesadą i wystarczy wyzerować pierwszy element (jak zauważono w innych odpowiedziach).


EDIT W celu wykorzystania memset , trzeba to string.h .


6
+1 - wybrałbym to, ponieważ zapewnia, że ​​wszystkie elementy tablicy są w znanym stanie.
ChrisBD

Jest to jednak sprzeczne z (epickim) wymogiem nieużywania pętli.
Michael Foukarakis

1
Chociaż memset prawdopodobnie nie jest zaimplementowany jako rekurencja, może tak być - w każdym przypadku iteracja jest przyzwoicie ukryta przed wzrokiem, co było rzekomym wymaganiem.
Steve Gilham

37

Zależy od tego, co masz na myśli mówiąc „pusty”:


3
Zmieniłoby to tylko wartość członków [0], a nie członków [1] poprzez członków [254]. Dobrze, jeśli uzyskujesz dostęp sekwencyjnie ... ale nie tak dobrze w innych przypadkach.
Thomas Owens

3
Po edycji OP wydaje się, że moje rozwiązanie powinno działać zgodnie z jego wymaganiami, ponieważ strcat () znajdzie bajt NULL i odpowiednio go potraktuje.
Felix

3
Nie jest to lepsze rozwiązanie. Tylko rozwiązanie innego problemu.
ypnos

4
Nie ma sposobu, aby „opróżnić” abstrakcyjną tablicę w C. Każda tablica zawiera coś, nawet jeśli są to zera. Pojęcie „opróżniania tablicy” ma zastosowanie tylko do logicznych interpretacji zawartości tablicy na wyższym poziomie. Na przykład zawartość tablicy może zostać zinterpretowana jako ciąg znaków C. W takim przypadku właściwym sposobem na „opróżnienie” jest ustawienie pierwszego elementu na „\ 0”. Dokładnie to, co zrobił Felix. Nie wiem, jakie inne interpretacje może mieć na myśli PO, ale bez sprecyzowania, wszystkie te próby z „memset” są po prostu bezsensownymi odpowiedziami na bezsensowne pytanie.
AnT

1
@tinkertim: Tutaj nie ma wartości NULL. I nie, „strcat” nie wie, jak obsłużyć NULL. Awaria, jeśli przekażesz mu NULL.
AnT

9

Nie przejmuj się próbą wyzerowania tablicy znaków, jeśli masz do czynienia z łańcuchami. Poniżej znajduje się prosty sposób pracy z ciągami znaków.

Kopiuj (przypisz nowy ciąg):

Concatenate (dodaj ciąg):

Pusta struna:

Takie proste.


8

członkowie char [255] = {0};


1
Nie, ponieważ nie określił, że należy to zrobić po inicjalizacji. Mogło to być szczególnie zrozumiałe w jego pierwszym przykładzie przed edycją i ponieważ jest to również bardzo powszechny przypadek użycia, aby wyczyścić tablicę.
user44556

Daję ci +2 jako rekompensatę, którą ci dał -1: P: D
stviper

5

EDYCJA: Biorąc pod uwagę najnowszą edycję pytania, nie będzie to już działać, ponieważ nie ma zakończenia zerowego - jeśli spróbujesz wydrukować tablicę, otrzymasz swoje znaki, a następnie kilka znaków nieczytelnych dla człowieka. Jednak zostawiam tę odpowiedź tutaj jako wiki społeczności dla potomności.

To powinno działać. Zgodnie z językiem programowania C:

Jeśli tablica ma stały rozmiar, liczba inicjatorów nie może przekraczać liczby elementów tablicy; jeśli jest ich mniej, pozostali członkowie są inicjowani z wartością 0.

Oznacza to, że każdy element tablicy będzie miał wartość 0. Nie jestem pewien, czy to jest to, co uważasz za „puste”, czy nie, ponieważ 0 jest prawidłową wartością a char.


Zależy to od tego, jak zdefiniujesz „pusty”. Znak o wartości 0 nie jest znakiem czytelnym dla człowieka, a tablica znaków jest w znanym stanie. Uznałbym to za puste. Robi również dokładnie to samo, co memset (jeśli moje wspomnienie memset jest poprawne - minęło zbyt dużo czasu, odkąd używałem C).
Thomas Owens

3

Nie można opróżnić tablicy jako takiej, ponieważ zawsze zawiera ona taką samą ilość danych.

W szerszym kontekście dane w tablicy mogą reprezentować pustą listę elementów, ale musi to być zdefiniowane dodatkowo do tablicy. Najczęstszym sposobem na to jest utrzymywanie liczby ważnych elementów (patrz odpowiedź przez pmg) lub ciągi kończące je znakiem zerowym (odpowiedź Felixa). Istnieją również bardziej skomplikowane sposoby, na przykład bufor pierścieniowy wykorzystuje dwa indeksy dla pozycji, w których dane są dodawane i usuwane.


3

wystarczy, biorąc pod uwagę Twoje wymagania.

Zauważ jednak, że nie jest to „opróżnianie” bufora. Pamięć jest nadal przydzielona, ​​mogą nadal istnieć w niej prawidłowe wartości znaków i tak dalej.


1
Można również zapisać jako * Members = 0;
eyalm

Nawet 0to ważny znak. Nie wiemy, czy memberssą traktowane jako string C, czy nie.
Sany


2

Poszedłbym z


W rzeczywistości ma to duży sens, ponieważ OP prosi o operację (opróżnianie), która nie jest częścią tablicy C - dlatego najlepiej zaimplementowałby nową strukturę danych, a sposób sygnalizowania struktury przez pmg jest pusty jest wystarczająco dobry.
Michael Foukarakis

Nie, to naprawdę nie ma sensu.

Kinopiko: Najwyraźniej nie rozumiesz wtedy podejścia
Christian

Kinopiko: przeczytaj odpowiedź starblue, ponieważ wyjaśnia ona moje rozumowanie lepiej, niż mogę wyjaśnić w komentarzu (dziękuję, starblue)
pmg

Hmm, to ciekawe podejście, czy Members_in_use nadal będzie tablicą? Czy mogę później zrobić; member_in_use [5] = wartość? Czy jest to odpowiednik memset (Members_in_use, 0, 255); jak stwierdził Steve? Jeśli tak, po co używać jednego zamiast drugiego?

1

Mówiąc „opróżnij tablicę”, jeśli masz na myśli reset do 0, możesz użyć bzero.

Jeśli chcesz wypełnić tablicę jakimś innym domyślnym znakiem, możesz użyć funkcji memset.


bzero i memset (zwykle) używają pętli.
Michael Foukarakis

1

prostsze jest lepsze - czy ma sens?

w tym przypadku tylko członkowie [0] = 0 działają. nie rób prostego pytania tak skomplikowanym.


0

Zrzeczenie się: Zwykle nie programuję w C, więc w moich przykładach mogą występować jakieś problemy ze składnią, ale mam nadzieję, że pomysły, które próbuję wyrazić, są jasne.

Jeśli „opróżnianie” oznacza „zawierający pusty ciąg”, możesz po prostu przypisać zeru pierwszemu elementowi tablicy, co skutecznie sprawi, że tablica będzie zawierać ciąg znaków empry:

Jeśli „opróżnianie” oznacza „zwolnienie używanej pamięci”, w pierwszej kolejności nie należy używać stałej tablicy znaków. Zamiast tego powinieneś zdefiniować wskaźnik do char, a następnie odpowiednio wykonać malloc / free (lub przypisanie string).

Przykład wykorzystujący tylko statyczne ciągi:


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.