membersihkan array karakter c


104

Saya pikir dengan mengatur elemen pertama ke null akan menghapus seluruh isi array karakter.

char my_custom_data[40] = "Hello!";
my_custom_data[0] = '\0';

Namun, ini hanya menyetel elemen pertama ke null.

atau

my_custom_data[0] = 0; 

daripada menggunakan memset, saya pikir 2 contoh di atas harus menghapus semua data.


1
Jared, mengapa Anda menyetel tag c ++? dia berbicara tentang "C" dan tidak menambahkan tag terkait C ++.
Johannes Schaub - litb

1
Ini berlaku sama baiknya untuk larik karakter di C ++, meskipun dia tidak menentukannya.
Adam Hawes

4
Saya telah menghapus tag C ++ untuk menghindari apa yang telah kita lihat dengan orang-orang yang menawarkan solusi khusus C ++
Alnitak

Jawaban:


113

Itu tergantung pada bagaimana Anda ingin melihat array. Jika Anda melihat array sebagai rangkaian karakter, maka satu-satunya cara untuk menghapus data adalah dengan menyentuh setiap entri. memsetmungkin cara paling efektif untuk mencapai ini.

Di sisi lain, jika Anda memilih untuk melihat ini sebagai string diakhiri C / C ++ null, pengaturan byte pertama ke 0 akan menghapus string secara efektif.


4
Kata kunci dalam jawabannya adalah 'efektif'. Hanya elemen pertama yang mulai disetel ke 0 dan sisanya masih memiliki nilai yang tidak ditentukan tetapi jika Anda memperlakukan array sebagai string yang diakhiri dengan null dan elemen pertama adalah null, maka string tersebut dianggap kosong.
Arnold Spence

memang, inilah jawabannya teman-teman.
Johannes Schaub - litb

@caparcode, tepatnya. Itulah mengapa sangat penting untuk memahami bagaimana array digunakan.
JaredPar

Ya, itulah yang seharusnya saya katakan di posting pertama saya. Karakter adalah string yang diakhiri. jadi salah satu dari ini akan melakukan trik itu. char [0] = '\ 0'; atau char [0] = 0. Saya tidak yakin, tetapi saya mendengar bahwa menggunakan '\ 0' lebih baik untuk menggunakan string yang dihentikan null.
ant2009

@robUK, ya kamu benar. Secara teknis '\ 0' sama dengan 0 (dalam ascii) tetapi Anda harus menggunakan '\ 0' karena itu membuat niat Anda jelas
Mark Testa

70

Array dalam C hanyalah sebuah lokasi memori, jadi memang, my_custom_data[0] = '\0';tugas Anda hanya menyetel elemen pertama ke nol dan membiarkan elemen lainnya tetap utuh.

Jika Anda ingin menghapus semua elemen larik, Anda harus mengunjungi setiap elemen. Itulah memsetuntuk:

memset(&arr[0], 0, sizeof(arr));

Ini umumnya cara tercepat untuk menangani masalah ini. Jika Anda dapat menggunakan C ++, pertimbangkan std :: fill sebagai gantinya:

char *begin = &arr;
char *end = begin + sizeof(arr);
std::fill(begin, end, 0);

1
Saya yakin versi kedua harus: std :: fill (arr, arr + sizeof (arr) / sizeof (arr [0]), 0);
David Rodríguez - dribeas

Klarifikasi: jangan gunakan sizeof dengan isi karena nanti Anda akan mendapat masalah dengan array int, long, double atau apa saja.
Zan Lynx

Saya lebih suka: std :: fill (& arr [0], & arr [arr_len], 0);
Zan Lynx

Zan Lynx, itu perilaku tidak terdefinisi. Anda tidak dapat melakukan & arr [arr_len]. tetapi Anda harus melakukan std :: fill (arr, arr + sizeof arr, 0); atau jika Anda memiliki panjang di suatu tempat std :: fill (arr, arr + arr_len, 0); dengan asumsi array char
Johannes Schaub - litb

Ini hanya berlaku di C. meskipun pertanyaannya jelas menargetkan C (orang lain menambahkan tag C ++, saya tidak tahu mengapa), std :: fill menunjukkan afinitas C ++ :)
Johannes Schaub - litb

25

Menurut Anda, mengapa menyetel satu elemen akan menghapus seluruh array? Di C, khususnya, hanya sedikit yang terjadi tanpa programmer secara eksplisit memprogramnya. Jika Anda menyetel elemen pertama ke nol (atau nilai apa pun), Anda telah melakukan hal itu, dan tidak lebih.

Saat menginisialisasi, Anda dapat mengatur array ke nol:

char mcd[40] = {0}; /* sets the whole array */

Kalau tidak, saya tidak tahu teknik apa pun selain memset, atau yang serupa.


Saya kira ini tergantung pada kompiler yang Anda gunakan
cocoafan

1
@cocoafan: Tidak, ini tidak bergantung pada kompilator. Ini adalah bagian dari spesifikasi bahasa. Setiap kompilator yang berperilaku berbeda tidak mengikuti bahasa C.
abelenky

Saya tidak tahu itu, terima kasih. Saya tidak dapat menemukan sumber daya di mana saya dapat membaca kasus khusus ini. Alangkah baiknya memilikinya sebagai bookmark.
cocoafan

1
Ini disebut inisialisasi parsial. Saya tidak memiliki spesifikasi C99, tetapi berikut adalah dua sumber: bit.ly/enBC2m "Anda tidak perlu menginisialisasi semua elemen dalam sebuah array. Jika sebuah array diinisialisasi sebagian, elemen yang tidak diinisialisasi menerima nilai 0 dari tipe yang sesuai. " bit.ly/f9asHH "Jika ada lebih sedikit penginisialisasi daripada elemen dalam larik, elemen yang tersisa secara otomatis diinisialisasi ke 0"
abelenky

Ini tidak berlaku untuk larik yang telah dideklarasikan dan diberi nilai bukan?
skinnedKnuckles

10

Menggunakan:

memset(my_custom_data, 0, sizeof(my_custom_data));

Atau:

memset(my_custom_data, 0, strlen(my_custom_data));

1
Opsi kedua ( memset(my_custom_data, 0, strlen(my_custom_data));) hanya akan menghapus '\ 0' pertama, yang mungkin berada di luar akhir larik. Ini mungkin, atau mungkin tidak, baik-baik saja.
brewmanz

9

Coba kode berikut:

void clean(char *var) {
    int i = 0;
    while(var[i] != '\0') {
        var[i] = '\0';
        i++;
    }
}

2
FYI - kode indentasi dengan 4 spasi atau pilih dan tekan tombol 'kode', yang terlihat seperti dua baris biner.
meagar

Solusi bagus jika Anda tidak ingin menyertakan string.h untuk memset ().
Akash Agarwal


6

Tolong temukan di bawah ini di mana saya telah menjelaskan dengan data dalam array setelah kasus 1 & kasus 2.

char sc_ArrData[ 100 ];
strcpy(sc_ArrData,"Hai" );

Kasus 1:

sc_ArrData[0] = '\0';

Hasil:

-   "sc_ArrData"
[0] 0 ''
[1] 97 'a'
[2] 105 'i'
[3] 0 ''

Kasus 2:

memset(&sc_ArrData[0], 0, sizeof(sc_ArrData));

Hasil:

-   "sc_ArrData"
[0] 0 ''
[1] 0 ''
[2] 0 ''
[3] 0 ''

Meskipun menyetel argumen pertama ke NULL akan melakukan triknya, disarankan menggunakan memset


4

Nggak. Yang Anda lakukan hanyalah menyetel nilai pertama ke '\ 0' atau 0.

Jika Anda bekerja dengan string yang dihentikan null, maka pada contoh pertama, Anda akan mendapatkan perilaku yang meniru apa yang Anda harapkan, namun memori masih disetel.

Jika Anda ingin menghapus memori tanpa menggunakan memset, gunakan for loop.


Saya mengatakan tidak pada putaran for. Cobalah untuk tidak menulis fungsi perpustakaan Anda sendiri yang "ditingkatkan" (dan biasanya tidak). Faktanya, memset dan memcpy yang agak khusus sering kali dimasukkan ke dalam kode mesin kustom untuk CPU berdasarkan pada apa yang diketahui tentang penyelarasan dan panjang data.
Zan Lynx

@Zan OP tidak ingin menggunakan memset (mungkin dia tertanam dan tidak memilikinya). Tapi ya, memset biasanya sangat optimal, dan kemungkinan besar lebih cepat daripada for loop.
Adam Hawes

Benar, bagaimanapun dia tidak ingin menggunakan memset, jadi saya menyarankan for loop.
Alan


2

Menulis karakter nol ke karakter pertama hanya melakukan itu. Jika Anda memperlakukannya sebagai string, kode yang mematuhi karakter penghentian nol akan memperlakukannya sebagai string nol, tetapi itu tidak sama dengan membersihkan data. Jika Anda ingin benar-benar menghapus data, Anda harus menggunakan memset.



1

Saya pikir dengan mengatur elemen pertama ke null akan menghapus seluruh isi array karakter.

Itu tidak benar seperti yang Anda temukan

Namun, ini hanya menyetel elemen pertama ke null.

Persis!

Anda perlu menggunakan memset untuk menghapus semua data, itu tidak cukup untuk mengatur salah satu entri ke null.

Namun, jika menyetel elemen array ke null berarti sesuatu yang istimewa (misalnya saat menggunakan string penghentian null di), mungkin cukup untuk menyetel elemen pertama ke null. Dengan cara itu setiap pengguna array akan mengerti bahwa array tersebut kosong meskipun array tersebut masih menyertakan karakter lama dalam memori


Jangan gunakan "memset" melebihi keterbacaan: stackoverflow.com/questions/453432/…
Johann Gerell

1

setel elemen pertama ke NULL. mencetak array karakter tidak akan mengembalikan apa-apa.



-3
void clearArray (char *input[]){
    *input = ' '; 
}

1
Ini bukan CLEARING, ini hanya mengatur karakter pertama ke ''! Saya pikir Anda ingin menulis * input = '\ 0'
stviper

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.