2009-01-15 24 views
13

Chúng ta đều biết những rắc rối tràn có thể gây ra, và đây là lý do tại sao strn * tồn tại - và hầu hết thời gian họ có ý nghĩa. Tuy nhiên, tôi đã nhìn thấy mã trong đó sử dụng strncmp để so sánh các thông số dòng lệnh như sau:Tôi có đúng là strcmp tương đương (và an toàn) cho các văn chương không?

Bây giờ, tôi đã có thể nghĩ rằng đây là không cần thiết và thậm chí nguy hiểm (đối với các thông số còn nó sẽ được dễ dàng để tính sai các nhân vật trong chữ).

strncmp dừng trên giá trị rỗng và mã đã giả định argv [i] bị hủy. Bất kỳ chuỗi ký tự nào được đảm bảo là không bị chấm dứt, vậy tại sao không sử dụng strcmp?

Có lẽ tôi đang thiếu một cái gì đó, nhưng tôi đã nhìn thấy điều này một vài lần và lần này nó hấp dẫn tôi đủ để yêu cầu.

Trả lời

16

có nó là hoàn toàn an toàn và được coi là thực hành tiêu chuẩn. Các chuỗi ký tự là đảm bảo được vô hiệu hóa đúng cách.

1

Theo như tôi biết, bạn hoàn toàn đúng - không có lý do gì để sử dụng strncmp thay vì strcmp. Có lẽ mọi người chỉ đang quá thận trọng (không nhất thiết là một điều xấu).

0

Có, sự hiện diện của chữ giới hạn kích thước của dữ liệu so sánh với kích thước của chữ. stncmp là dự phòng ở đây.

Một số người có thể nói rằng strncmp là một thói quen tốt để tham gia, nhưng điều này bị thừa nhận bởi sự cố khi đếm ký tự.

0

tôi có lẽ sẽ viết một cái gì đó như thế này trong C (nếu tôi đã sử dụng rất nhiều strncmp & không muốn làm đếm ký tự):

if(... strncmp(argv[i], "--help", sizeof("--help") - 1) == 0 
+0

nhưng điều đó lặp chuỗi hai lần không cần thiết. Ít nhất sử dụng (sizeof ("- help") - 1). Và có, sizeof hoạt động chính xác trên chuỗi ký tự từ kích thước của chúng được biết tại thời gian biên dịch. –

+0

Ngoài ra, không, strlen không tính giá trị rỗng. –

+0

Tôi không chắc chắn về sizeof so với chuỗi ký tự. Nói chung, tôi muốn đề nghị C + + và std :: string. :-) –

0

Nó có thể không được thực hiện cho an toàn. Nó có thể đã được thực hiện để kiểm tra chỉ bắt đầu tham số dòng lệnh. Nhiều chương trình chỉ kiểm tra đầu của các công tắc dòng lệnh và bỏ qua phần còn lại.

4

Bạn nói đúng.

Hơn nữa, ví dụ bạn đã cung cấp sẽ khớp với "--help" nhưng cũng có mọi thứ bắt đầu bằng "--help" (như "--help-me").

Một trường hợp hiếm hoi trong đó quá mức == sai.

12

Bạn có chắc chắn rằng mã không được dự định để khớp trên "--helpmedosoemthingwithareallylongoptionname"?

+0

Điều này có vẻ giống như một khả năng khác biệt. –

+0

đó là một điểm rất tốt. Tôi không * nghĩ * vì vậy trong trường hợp này vì tất cả các commandline args được thực hiện theo cách này – Draemon

+1

Mục đích nhiều khả năng là khớp với những thứ như '--help = foobar', nhưng tiếc là nó cũng sẽ khớp với những thứ như' --helper- chương trình'. Tôi nghĩ rằng mã chỉ là lỗi. –

1

Như những người khác đã nói, strcmp() là hoàn toàn an toàn để sử dụng với các chữ. Nếu bạn muốn sử dụng strncmp(), hãy thử điều này:

strncmp(argv[i], "--help", sizeof("--help")) 

Hãy để trình biên dịch tính toán cho bạn!

Điều này sẽ chỉ khớp với chuỗi chính xác "--help". Nếu bạn muốn khớp tất cả các chuỗi bắt đầu bằng "--help" (như mã của bạn), hãy sử dụng sizeof() - 1 để không bao gồm '\0' cuối cùng.

+1

bạn có nghĩa là sizeof ("- help") - 1, vì sizeof sẽ bao gồm null terminator. –

+0

@Evan: phụ thuộc vào những gì bạn muốn làm - đã chỉnh sửa câu trả lời của tôi;) – Christoph

+0

Sau đó, tại sao sử dụng strncmp() ở nơi đầu tiên? Nhiều chi tiết và dư thừa hơn. Chỉ cần sử dụng strcmp() nếu bạn chỉ muốn phù hợp với chuỗi chính xác. –

0

er ... về mặt kỹ thuật không thể có điều gì đó như thế này xảy ra?

char *cp1 = "help"; 
cp1[4] = '!'; // BAD PRACTICE! don't try to mutate a string constant! 
// Especially if you remove the terminating null! 
    ... 
strcmp(some_variable, "help"); 
// if compiler is "smart" enough to use the same memory to implement 
// both instances of "help", you are screwed... 

Tôi đoán đây là một trường hợp bệnh lý và/hoặc rác-in, rác thải ra ("Doc, một điều đau khổ khi tôi Whack đầu tôi vào tường!" "Vậy thì đừng làm điều đó!"). ..

(ps tôi chỉ nâng cao vấn đề này - nếu bạn cảm thấy bài viết này muddies nước, bình luận một cách thích hợp & tôi sẽ xóa nó)

+0

Kể từ khi sửa đổi chuỗi bị cấm, tôi không nghĩ rằng bạn có thể nói rằng mã khác là sai bởi vì nó bị ảnh hưởng bởi nó. Nó giống như nói rằng có một lỗi trong một chương trình bởi vì nó có thể được thực hiện bằng cách khai thác tràn bộ đệm trong một chương trình khác. – Draemon

+0

Nếu hai chuỗi được lưu trữ trong cùng một vị trí, thì sửa đổi sẽ ảnh hưởng đến cả hai chuỗi và so sánh sẽ vẫn bằng nhau - hoặc bạn nhận được một kết xuất lõi. Tất nhiên, hành vi là không xác định; bất cứ điều gì có thể - Google cho 'mũi quỷ' nếu bạn muốn. –

+0

Một chương trình thực hiện điều này là không đúng định dạng, cho đến khi chương trình của bạn liên quan đến tất cả logic kết thúc ở đó. – Thomas

Các vấn đề liên quan