Làm thế nào để làm trống một mảng char?


83

Có một mảng ký tự như các thành viên char [255]. Làm thế nào tôi có thể làm trống nó hoàn toàn mà không cần sử dụng vòng lặp?

char members[255];

Bởi "trống", tôi có nghĩa là nếu nó có một số giá trị được lưu trữ trong đó thì nó không nên. Ví dụ: nếu tôi thực hiện strcat thì giá trị cũ sẽ không còn

members = "old value";

//empty it efficiently
strcat(members,"new"); // should return only new and not "old value new"

3
"Làm trống một mảng" nghĩa là gì?
pmg

4
thành viên [0] = thành viên [1] = thành viên [2] = thành viên [3] ... = thành viên [255] = 0 không có vòng lặp đó;)
John La Rooy

18
Vì vậy, "mảng" của bạn là một loại mảng đặc biệt: nó là một string. Để "trống rỗng" một chuỗi, thiết lập nó là yếu tố đầu tiên để '\ 0':members[0] = '\0';
PMG

Cộng đồng dường như ủng hộ memset. Nhưng đó có phải là cách hiệu quả nhất với yêu cầu của tôi không?
Alex Xander

2
@Alex Xander: "Cộng đồng" rõ ràng là sai trong trường hợp này. Có những tình huống yêu cầu 'memset' (như xóa dữ liệu để ngăn việc sử dụng trái phép), nhưng đối với thiết lập lại chuỗi đơn giản (như trong trường hợp của bạn), câu trả lời đúng là chỉ có phần tử đầu tiên.
AnT

Câu trả lời:


170

sử dụng

  memset(members, 0, 255);

nói chung

  memset(members, 0, sizeof members);

nếu mảng nằm trong phạm vi, hoặc

  memset(members, 0, nMembers * (sizeof members[0]) );

nếu bạn chỉ có giá trị con trỏ và nMembers là số phần tử trong mảng.


CHỈNH SỬA Tất nhiên, bây giờ yêu cầu đã thay đổi từ nhiệm vụ chung là xóa một mảng thành hoàn toàn đặt lại một chuỗi, memsetlà quá mức cần thiết và chỉ cần thêm phần tử đầu tiên là đủ (như đã lưu ý trong các câu trả lời khác).


CHỈNH SỬA Để sử dụng memset , bạn phải bao gồm string.h .


6
+1 - Tôi sẽ làm điều này vì nó đảm bảo rằng tất cả các phần tử mảng đều ở trạng thái đã biết.
ChrisBD

Tuy nhiên, nó đi ngược lại yêu cầu (sử thi) của việc không sử dụng vòng lặp.
Michael Foukarakis

1
Mặc dù memset có thể không được triển khai dưới dạng đệ quy, nhưng có thể - trong cả hai trường hợp, phép lặp được ẩn khỏi tầm nhìn, đó là yêu cầu rõ ràng.
Steve Gilham

36

Phụ thuộc vào những gì bạn có nghĩa là "trống":

members[0] = '\0';

3
Điều đó sẽ chỉ thay đổi giá trị của thành viên [0], không phải từ thành viên [1] qua thành viên [254]. Tốt nếu bạn đang truy cập tuần tự ... nhưng không tốt trong các trường hợp khác.
Thomas Owens

3
Sau khi OP chỉnh sửa, có vẻ như giải pháp của tôi sẽ phù hợp với yêu cầu của anh ấy, vì strcat () sẽ tìm byte NULL và xử lý nó cho phù hợp.
Felix

3
Không phải là một giải pháp tốt hơn. Chỉ là một giải pháp cho một vấn đề khác.
ypnos

4
Không có cách nào để "làm trống" một mảng trừu tượng trong C. Mọi mảng đều chứa một cái gì đó, ngay cả khi nó là số 0. Khái niệm "làm trống mảng" chỉ có thể áp dụng cho các diễn giải logic cấp cao hơn về nội dung mảng. Ví dụ: nội dung của mảng có thể được hiểu là chuỗi C. Trong trường hợp đó, cách thích hợp để "làm trống" là đặt phần tử đầu tiên thành '\ 0'. Chính xác những gì Felix đã làm. Tôi không biết OP có thể có những cách giải thích nào khác, nhưng nếu không làm cho nó cụ thể hơn, tất cả những nỗ lực đó với 'memset' chỉ là câu trả lời vô nghĩa cho một câu hỏi vô nghĩa.
AnT

1
@tinkertim: Không có NULL ở đây. Và không, 'strcat' không biết cách xử lý NULL. Nó sẽ sập nếu bạn chuyển NULL cho nó.
AnT

9

Đừng bận tâm cố gắng loại bỏ mảng char của bạn nếu bạn đang xử lý các chuỗi. Dưới đây là một cách đơn giản để làm việc với chuỗi ký tự.

Sao chép (gán chuỗi mới):

strcpy(members, "hello");

Nối (thêm chuỗi):

strcat(members, " world");

Chuỗi trống:

members[0] = 0;

Đơn giản như thế.


8

char thành viên [255] = {0};


1
Không, vì anh ấy không chỉ định rằng nó phải được thực hiện sau khi khởi tạo. Đặc biệt điều này có thể đã được hiểu bởi ví dụ đầu tiên của anh ấy trước khi chỉnh sửa và bởi vì nó cũng là trường hợp sử dụng rất phổ biến để xóa một mảng.
user44556

Tôi cung cấp cho bạn 2 như bồi thường đến nỗi đã ban bạn -1: P: D
stviper

5

CHỈNH SỬA: Với bản chỉnh sửa gần đây nhất cho câu hỏi, điều này sẽ không còn hoạt động vì không có kết thúc bằng rỗng - nếu bạn cố gắng in mảng, bạn sẽ nhận được các ký tự của mình theo sau là một số ký tự không thể đọc được. Tuy nhiên, tôi để câu trả lời này ở đây dưới dạng wiki cộng đồng cho hậu thế.

char members[255] = { 0 };

Cần làm việc. Theo Ngôn ngữ lập trình C:

Nếu mảng có kích thước cố định, số bộ khởi tạo không được vượt quá số thành viên của mảng; nếu có ít hơn, các thành viên còn lại được khởi tạo bằng 0.

Điều này có nghĩa là mọi phần tử của mảng sẽ có giá trị bằng 0. Tôi không chắc đó có phải là giá trị mà bạn cho là "trống" hay không, vì 0 là giá trị hợp lệ cho a char.


Nó phụ thuộc vào cách bạn định nghĩa "rỗng". Ký tự có giá trị 0 không phải là ký tự con người có thể đọc được và mảng ký tự ở trạng thái đã biết. Tôi sẽ coi đó là trống rỗng. Nó cũng hoạt động tương tự như memset (nếu hồi ức của tôi về memset là chính xác - đã quá lâu tôi không sử dụng C).
Thomas Owens

3

Bạn không thể làm trống một mảng như vậy, nó luôn chứa cùng một lượng dữ liệu.

Trong ngữ cảnh lớn hơn, dữ liệu trong mảng có thể đại diện cho một danh sách rỗng các mục, nhưng điều đó phải được xác định ngoài mảng. Các cách phổ biến nhất để làm điều này là giữ số lượng các mục hợp lệ (xem câu trả lời bằng pmg) hoặc cho các chuỗi để kết thúc chúng bằng một ký tự 0 (câu trả lời của Felix). Cũng có nhiều cách phức tạp hơn, ví dụ như một bộ đệm vòng sử dụng hai chỉ số cho các vị trí mà dữ liệu được thêm vào và loại bỏ.


3
members[0] = 0;

là đủ, với yêu cầu của bạn.

Tuy nhiên, lưu ý rằng đây không phải là "làm trống" bộ đệm. Bộ nhớ vẫn được cấp phát, các giá trị ký tự hợp lệ vẫn có thể tồn tại trong đó, v.v.


1
Cũng có thể được viết là * thành viên = 0;
eyalm

Even 0là một ký tự hợp lệ. Chúng tôi không biết liệu memberscó được coi là chuỗi C hay không.
Sany


2

Tôi sẽ đi với

members_in_use = 0;

Nó thực sự có ý nghĩa, vì OP đang yêu cầu một hoạt động (làm trống) không phải là một phần của mảng C - do đó, lý tưởng là anh ta sẽ triển khai một cấu trúc dữ liệu mới và cách pmg báo hiệu cấu trúc trống. Là đủ tốt.
Michael Foukarakis

Không, nó thực sự không có ý nghĩa gì cả.

Kinopiko: Rõ ràng là bạn không hiểu cách tiếp cận sau đó
Christian

Kinopiko: đọc câu trả lời starblue vì nó giải thích lý luận của tôi tốt hơn tôi có thể giải thích trong một chú thích (cảm ơn bạn starblue)
PMG

Hmm, đây là một cách tiếp cận thú vị, liệu Member_in_use vẫn là một mảng chứ? Sau này tôi có thể làm một; member_in_use [5] = giá trị? Điều này có tương đương với memset (Member_in_use, 0, 255); như Steve đã nêu? Nếu vậy, tại sao lại sử dụng cái này thay vì cái kia?

1

Bằng cách "làm trống một mảng" nếu bạn muốn đặt lại về 0, thì bạn có thể sử dụng bzero.

#include <strings.h>  
void bzero(void *s, size_t n);  

Nếu bạn muốn điền vào mảng bằng một số ký tự mặc định khác thì bạn có thể sử dụng hàm memset.

#include <string.h>  
void *memset(void *s, int c, size_t n);  

bzero và memset (thường) đều sử dụng một vòng lặp.
Michael Foukarakis

1

đơn giản hơn là tốt hơn - có ý nghĩa?

trong trường hợp này, chỉ thành viên [0] = 0 hoạt động. đừng làm cho một câu hỏi đơn giản trở nên phức tạp.


0

Tuyên bố từ chối trách nhiệm: Tôi không thường lập trình bằng C nên có thể có bất kỳ lỗi cú pháp nào trong các ví dụ của tôi, nhưng tôi hy vọng ý tưởng mà tôi cố gắng diễn đạt là rõ ràng.

Nếu "rỗng" có nghĩa là "chứa một chuỗi rỗng", bạn có thể chỉ định mục đầu tiên của mảng bằng 0, điều này sẽ làm cho mảng có chứa một chuỗi rỗng:

members[0] = 0;

Nếu "làm trống" có nghĩa là "giải phóng bộ nhớ mà nó đang sử dụng", thì ngay từ đầu bạn không nên sử dụng một mảng char cố định. Thay vào đó, bạn nên xác định một con trỏ tới char, và sau đó thực hiện phép gán malloc / free (hoặc chuỗi) nếu thích hợp.

Một ví dụ chỉ sử dụng chuỗi tĩnh:

char* emptyString="";
char* members;

//Set string value
members = "old value";

//Empty string value
member = emptyString

//Will return just "new"
strcat(members,"new");

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.