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.

ant2009
sumber
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.

JaredPar
sumber
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);
John Feminella
sumber
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.

abelenky
sumber
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));
Jake1164
sumber
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++;
    }
}
Cristian Altamirano
sumber
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
7

Mengapa tidak digunakan memset()? Begitulah cara melakukannya.

Mengatur elemen pertama membuat sisa memori tidak tersentuh, tetapi fungsi str akan memperlakukan data sebagai kosong.

John Fricker
sumber
1
Jangan gunakan memset melebihi keterbacaan: stackoverflow.com/questions/453432/…
Johann Gerell
1
lalu apa jawabanmu?
mkb
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

Akaanthan Ccoder
sumber
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.

Alan
sumber
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
3

Anda harus menggunakan memset. Menyetel elemen pertama saja tidak akan berfungsi, Anda perlu menyetel semua elemen - jika tidak, bagaimana Anda bisa menyetel hanya elemen pertama ke 0?

Michael
sumber
memset tidak boleh digunakan melebihi keterbacaan: stackoverflow.com/questions/453432/…
Johann Gerell
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.

tvanfosson.dll
sumber
2

Saya biasanya hanya melakukan seperti ini:

memset(bufferar, '\0', sizeof(bufferar));
Jevgenij Kononov
sumber
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

hhafez.dll
sumber
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.


sumber
1

Bagaimana dengan yang berikut ini:

bzero(my_custom_data,40);
codeconnundrum
sumber
-3
void clearArray (char *input[]){
    *input = ' '; 
}
serigala
sumber
1
Ini bukan CLEARING, ini hanya mengatur karakter pertama ke ''! Saya pikir Anda ingin menulis * input = '\ 0'
stviper
-4

Coba yang berikut ini:

strcpy(my_custom_data,"");
Greg Grady
sumber